Reputation: 95
I'm following this example but using a functional component. My field is controlled throught state and it works with no problem. However, none of my functions that update the state are working:
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;
Both the validateForm and validateUsername are working, except they're not setting the state. How come?
Upvotes: 0
Views: 112
Reputation: 979
Attention: using setState inside useEffect maybe create an infinite loop, if you update state inside it and re-render run again and the useEffect change the same state again and loop again.
Replace your setState to this change:
setState(state => ({ ...state, username: username }));
Upvotes: 3
Reputation: 558
First of all, you need to add methods called in useEffect
to it dependencies
Write your functions with useCallback
hooks as you use them, and wasn't to create new function after every render.
And you must put everything in dependencies which can be changed during the time to have their new values after the change, es they will be memoized
I updated your code and put it here, please check is it what you want?
https://codesandbox.io/s/zealous-grothendieck-y438z?file=/src/App.js
Upvotes: 0