UseEffect hook tidak memperbarui status

Aug 21 2020

Saya mengikuti contoh ini tetapi menggunakan komponen fungsional. Bidang saya dikendalikan melalui keadaan dan bekerja tanpa masalah. Namun, tidak ada fungsi saya yang memperbarui status yang berfungsi:

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;

Baik validateForm dan validateUsername berfungsi, kecuali keduanya tidak menyetel status. Bagaimana bisa?

Jawaban

3 BaruchMashasha Aug 21 2020 at 12:23

Perhatian: menggunakan setState di dalam useEffect mungkin membuat loop tanpa batas, jika Anda memperbarui status di dalamnya dan menjalankan ulang render lagi dan useEffect mengubah status yang sama lagi dan mengulang lagi.

Ganti setState Anda ke perubahan ini:

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

Pertama-tama, Anda perlu menambahkan metode yang dipanggil useEffectke dalamnyadependencies

Tulis fungsi Anda dengan useCallbackkait saat Anda menggunakannya, dan bukan untuk membuat fungsi baru setelah setiap render.

Dan Anda harus meletakkan semuanya dalam dependensi yang dapat diubah selama ini untuk memiliki nilai baru setelah perubahan, es itu akan dimoisasi

Saya memperbarui kode Anda dan meletakkannya di sini, harap periksa apakah itu yang Anda inginkan?

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