UseEffect hook ไม่อัปเดตสถานะ

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

ข้อควรสนใจ: การใช้ setState ภายใน useEffect อาจสร้างลูปที่ไม่มีที่สิ้นสุดหากคุณอัปเดตสถานะภายในและเรนเดอร์รันอีกครั้งและ useEffect เปลี่ยนสถานะเดิมอีกครั้งและวนซ้ำอีกครั้ง

แทนที่ setState ของคุณเป็นการเปลี่ยนแปลงนี้:

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

ก่อนอื่นคุณต้องเพิ่มเมธอดที่เรียกuseEffectเข้าไปdependencies

เขียนฟังก์ชันของคุณด้วยuseCallbackhooks เมื่อคุณใช้งานและไม่ต้องสร้างฟังก์ชันใหม่หลังจากการแสดงผลทุกครั้ง

และคุณต้องใส่ทุกอย่างไว้ในการอ้างอิงซึ่งสามารถเปลี่ยนแปลงได้ในช่วงเวลาที่จะมีค่าใหม่หลังจากการเปลี่ยนแปลงพวกเขาจะถูกบันทึกไว้

ฉันอัปเดตรหัสของคุณและวางไว้ที่นี่โปรดตรวจสอบว่าเป็นสิ่งที่คุณต้องการหรือไม่?

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