UseEffect 후크가 상태를 업데이트하지 않음

Aug 21 2020

나는 다음있어 이 예제를 하지만 기능적 구성 요소를 사용하여. 내 분야는 상태를 통해 제어되며 문제없이 작동합니다. 그러나 상태를 업데이트하는 내 기능이 작동하지 않습니다.

function FormFieldTest() {

    const [state, setState] = useState({
        username: '',
        usernameValid: false,
        formValid: false,
        errorMsg: {}
    });

    useEffect(()=> {
        validateUsername();
        validateForm();
    },[state.username]);

    const updateUsername = (username) => {
        setState({...state, username: username});
    }

    const validateUsername = () => {
        let username = state.username;
        let usernameValid = true;
        let errorMsg = {...state.errorMsg};

        if(username.length < 3) {
            usernameValid = false;
            errorMsg.username = "Must be at least 3 characters long."
        }
        setState({...state,
            usernameValid: usernameValid,
            errorMsg: errorMsg
        });
    }

    const validateForm = () => {
        const usernameValid = state.usernameValid;

        setState({
            ...state,
            formValid: usernameValid
        });
    }

    return (
        <div className="container">
            <form>
                <div className="form-group">
                    <label htmlFor="username">Username</label>
                    <ValidationMessage valid={state.usernameValid} message={state.errorMsg.username} />
                    <input type="text" id="username" name="username" className="form-field" value={state.username} onChange={(e)=>updateUsername(e.target.value)} />
                </div>
            </form>
        </div>
    )
}

export default FormFieldTest;

validateForm과 validateUsername이 모두 작동하지만 상태를 설정하지 않습니다. 어째서?

답변

3 BaruchMashasha Aug 21 2020 at 12:23

주의 : useEffect 내부에서 setState를 사용하면 내부의 상태를 업데이트하고 다시 렌더링하고 useEffect가 동일한 상태를 다시 변경하고 다시 반복하면 무한 루프가 생성 될 수 있습니다.

setState를 다음 변경으로 바꿉니다.

 setState(state => ({ ...state, username: username }));
Hovakimyan Aug 21 2020 at 12:29

먼저 호출 된 메서드를 추가해야 useEffect합니다.dependencies

useCallback사용할 때마다 후크로 함수 를 작성하고 렌더링 할 때마다 새 함수를 만들지 않았습니다.

그리고 변경 후 새로운 값을 가지려면 시간 동안 변경 될 수있는 모든 것을 종속성에 넣어야합니다.

코드를 업데이트하고 여기에 넣었습니다. 원하는 것이 맞는지 확인하십시오.

https://codesandbox.io/s/zealous-grothendieck-y438z?file=/src/App.js