양식 제출시 양식 유효성 검사를 수행하는 동안 구성 요소가 React에서 업데이트되지 않습니다.

락쉬미 프리 야 무 쿤단

반응에 로그인이 있습니다.

import React, { Fragment, useState } from 'react';
import { useHistory } from "react-router-dom";
import { useDispatch } from 'react-redux';
import { Link } from 'react-router-dom';

import { auth } from '../actions';


export const Login = () => {
   let history = useHistory();
   const dispatch = useDispatch();

   const [email, setEmail] = useState('');
   const [password, setPassword] = useState('');
   const [error, setError] = useState({email: '', password: ''});

   const validEmailRegex = RegExp(/^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|. 
    (\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i);

   const handleChange = e => {
      e.persist();
      const { name, value } = e.target;
      let validationError = error;

      switch(name) {
        case 'email':
            setEmail(value);
            validationError.email = validEmailRegex.test(value) ? '' : 'Email is not valid';
            break;
        case 'password':
            setPassword(value)
            validationError.password = value.length < 8 ? 'Password must be 8 characters 
            long!': '';
            break;
        case 'submit':
            validationError.email = email.length < 1 ? 'Email is required'  : '';
            validationError.password = password.length < 1 ? 'Password is required'  : '';
        default:
            break;
      };
    setError(validationError);
    console.log('in change', error)
   };

const validateForm = (errors) => {
    let valid = true;
    Object.values(errors).forEach(
      // if we have an error string set valid to false
      (val) => val.length > 0 && (valid = false)
    );
    return valid;
};

const validate = () => {
    console.log('email,password', email, password);
    let validationError = error;
    if(!email){
        validationError.email = 'Email is required';
    }
    if(!password){
        validationError.password = 'Password is required';
    }
    setError(validationError);
    console.log('in validate',error)
};

const onSubmit = e => {
    e.preventDefault();
    validate();
    console.log('error on submit', error);
    if(validateForm(error)) {
        dispatch(auth(email, password, true));
        history.replace('/home');
      }else{
        console.error('Invalid Form', error)
      }
};
return (
    <Fragment>
        <div className="w-full max-w-sm container mt-20 mx-auto">
            <form onSubmit={onSubmit}>
                <div className="w-full mb-5">
                    <label className="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" htmlFor="email">
                        Email
                    </label>
                    <input className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:text-gray-600" value={email} name='email' onChange={(e) => handleChange(e)} type="text" placeholder="Email" />
                    { error && <span style={{color: "red"}}>{error['email']}</span>}
                </div>
                <div className="w-full  mb-5">
                    <label className="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" htmlFor="password">
                        Password
                    </label>
                    <input className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:text-gray-600" value={password} name='password' onChange={(e) => handleChange(e)} type="password" placeholder="Password" />
                    { error && <span style={{color: "red"}}>{error['password']}</span>}
                </div>
                <div className="flex items-center justify-between">
                    <button className="mt-5 bg-green-400 w-full hover:bg-green-500 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline">
                        Login
                    </button>
                </div>
                <div className="text-center mt-4 text-gray-500"><Link to='/'>Cancel</Link></div>
            </form>
        </div>
    </Fragment>
)

}

onchange에 필드 유효성 검사를 추가하고 제출하면 onchange 유효성 검사가 올바르게 작동하고 오류가 표시됩니다. 제출시 유효성 검사도 잘 작동하지만 필드를 변경하지 않고 제출하려고하면 구성 요소에 오류가 표시되지 않습니다.

나는 반응이 처음이며 이것이 올바른 방법인지 모르겠습니다. 미리 감사드립니다.

이스 파란

코드 샌드 박스에 코드를 넣었는데 제대로 작동하는 것 같습니다. className속성을 제거 하고 redux가져 오기 와 같은 문제를 테스트하는 데 필요하지 않은 항목을 주석 처리했습니다 .

className속성을 제거했기 때문에 CSS오류 span가 실제로 렌더링되지만 표시되지 않는 문제 가 될 수 있습니다 (브라우저의 개발 도구를 확인하여 실제로 없는지 확인하십시오 span).

또한 상태 처리 + 유효성 검사가 상당히 복잡해질 수 있고 많은 솔루션이 있기 때문에 많은 양식을 사용하는 경우 라이브러리를 사용하는 것이 좋습니다.
나는 내 자신의 라이브러리 ( 반응 유창한 형식)를 썼습니다 . 자유롭게 확인해보세요.

편집하다

여기서 문제는를 error사용 하여 객체를 업데이트 할 때 setError항상 동일한 객체 참조를 전달한다는 것입니다.

// this is not doing a copy
// validationError will have the same reference as error
let validationError = error;

// ...

// following line will not trigger a rerender
setError(validationError);

이후 errorvalidationError같은 기준을 가지고, react따라서 원인이됩니다, 변화가 일어나지있다 asume 것입니다 상태 업데이트의 구제 . 상태에서 복잡한 유형 (객체 또는 배열과 같은)으로 작업하는 경우 이전 참조를 조정하는 대신 항상 새 참조를 만들어야합니다.

// this is an actual copy using the spread operator
// validationError will have different reference than error
let validationError = {...error};

// ...

// triggers rerender as expected
setError(validationError);

2 편집

호출 할 때 validate업데이트 된 validationError개체 를 사용하기 위해에 대한 반환 값을 추가했습니다 validateForm.

const validate = () => {
    //..
    let validationError = { ...error };

    // ...

    return validationError;
};

const onSubmit = e => {
    // ...
    const validationError = validate();

    if (validateForm(validationError)) {
    //...
    }
};

업데이트 된 코드 샌드 박스를 참조하십시오 .

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관