UseEffect hook ไม่อัปเดตสถานะ
ฉันทำตามตัวอย่างนี้แต่ใช้ส่วนประกอบที่ใช้งานได้ ฟิลด์ของฉันถูกควบคุมสถานะการทะลุและใช้งานได้โดยไม่มีปัญหา อย่างไรก็ตามไม่มีฟังก์ชันใดของฉันที่อัปเดตสถานะใช้งานได้:
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 ใช้งานได้ยกเว้นไม่ได้ตั้งค่าสถานะ มาได้ยังไง?
คำตอบ
ข้อควรสนใจ: การใช้ setState ภายใน useEffect อาจสร้างลูปที่ไม่มีที่สิ้นสุดหากคุณอัปเดตสถานะภายในและเรนเดอร์รันอีกครั้งและ useEffect เปลี่ยนสถานะเดิมอีกครั้งและวนซ้ำอีกครั้ง
แทนที่ setState ของคุณเป็นการเปลี่ยนแปลงนี้:
setState(state => ({ ...state, username: username }));
ก่อนอื่นคุณต้องเพิ่มเมธอดที่เรียกuseEffectเข้าไปdependencies
เขียนฟังก์ชันของคุณด้วยuseCallbackhooks เมื่อคุณใช้งานและไม่ต้องสร้างฟังก์ชันใหม่หลังจากการแสดงผลทุกครั้ง
และคุณต้องใส่ทุกอย่างไว้ในการอ้างอิงซึ่งสามารถเปลี่ยนแปลงได้ในช่วงเวลาที่จะมีค่าใหม่หลังจากการเปลี่ยนแปลงพวกเขาจะถูกบันทึกไว้
ฉันอัปเดตรหัสของคุณและวางไว้ที่นี่โปรดตรวจสอบว่าเป็นสิ่งที่คุณต้องการหรือไม่?
https://codesandbox.io/s/zealous-grothendieck-y438z?file=/src/App.js