Il hook UseEffect non aggiorna lo stato
Sto seguendo questo esempio ma utilizzo un componente funzionale. Il mio campo è controllato dallo stato e funziona senza problemi. Tuttavia, nessuna delle mie funzioni che aggiornano lo stato funziona:
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;
Sia validateForm che validateUsername funzionano, tranne per il fatto che non stanno impostando lo stato. Come mai?
Risposte
Attenzione: l'uso di setState all'interno di useEffect potrebbe creare un ciclo infinito, se si aggiorna lo stato al suo interno e si esegue nuovamente il rendering, useEffect cambia di nuovo lo stesso stato e si ripete.
Sostituisci il tuo setState con questa modifica:
setState(state => ({ ...state, username: username }));
Prima di tutto, devi aggiungere metodi chiamati useEffectad essodependencies
Scrivi le tue funzioni con gli useCallbackhook mentre le usi, e non creare nuove funzioni dopo ogni rendering.
E devi mettere tutto in dipendenze che possono essere modificate nel tempo per avere i loro nuovi valori dopo la modifica, ad esempio saranno memoizzati
Ho aggiornato il tuo codice e l'ho inserito qui, controlla se è quello che vuoi?
https://codesandbox.io/s/zealous-grothendieck-y438z?file=/src/App.js