UseEffect hook không cập nhật trạng thái
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
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 }));
Trước hết, bạn cần thêm các phương thức được gọi vào useEffectnódependencies
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