UseEffect hook không cập nhật trạng thái

Aug 21 2020

Tôi đang làm theo ví dụ này nhưng sử dụng một thành phần chức năng. Lĩnh vực của tôi được kiểm soát trạng thái hạn chế và nó hoạt động không có vấn đề gì. Tuy nhiên, không có hàm nào cập nhật trạng thái của tôi đang hoạt động:

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;

Cả validateForm và validateUsername đều đang hoạt động, ngoại trừ chúng không thiết lập trạng thái. Làm thế nào mà?

Trả lời

3 BaruchMashasha Aug 21 2020 at 12:23

Chú ý: sử dụng setState bên trong useEffect có thể tạo ra một vòng lặp vô hạn, nếu bạn cập nhật trạng thái bên trong nó và re-render chạy lại và useEffect lại thay đổi trạng thái đó và lặp lại.

Thay thế setState của bạn thành thay đổi này:

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

Trước hết, bạn cần thêm các phương thức được gọi vào useEffectdependencies

Viết các hàm của bạn bằng các useCallbackhook khi bạn sử dụng chúng và không phải để tạo hàm mới sau mỗi lần hiển thị.

Và bạn phải đặt mọi thứ trong các phụ thuộc có thể thay đổi trong thời gian để có các giá trị mới của chúng sau khi thay đổi, vì chúng sẽ được ghi nhớ

Tôi đã cập nhật mã của bạn và đặt nó ở đây, vui lòng kiểm tra xem nó có đúng như những gì bạn muốn không?

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