React - Manage many state updates
Yacine C
Posted on April 18, 2023
Managing multiple states can rapidly become a complex task.
In effect, it can create some synchronous problems. Letβs say you have this component:
const MyComponent = () => {
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const handleClick = () => {
setLoading(true);
someMethod()
.then((newUsers) => {
setUsers(newUsers);
setLoading(false);
});
};
return loading ? (<Loader />) : (<button onClick={handleClick}>Update</button>);
};
The code is currently working. However, as it becomes more complex and has more states, you may encounter issues with its values and component refreshing.
To avoid this kind of behavior, you can store all your data in the same object.
const MyComponent = () => {
const [object, setObject] = useState({
loading: false,
users: []
});
const handleClick = () => {
setObject({...object, loading: true});
someMethod()
.then((newUsers) => {
setObject({...object, users: newUsers, loading: false});
});
};
return loading ? (<Loader />) : (<button onClick={handleClick}>Update</button>);
};
In this case, that's totally fine because our object is pretty simple. However, if we have to deal with more states, it's better to use a reducer to externalize the object updates.
const reducer = (state, action) => {
switch(action.type) {
case "start":
return {...state, loading: true}
case "end":
return {...state, users: action.newUsers, loading: false}
}
}
const App = () => {
const [object, dispatch] = useReducer(reducer, {
loading: false,
users: []
});
const handleClick = () => {
dispatch({type: "start"});
someMethod()
.then((newUsers) => {
dispatch({type: "end", newUsers});
});
};
return object.loading ?
(<Loader />) :
(<div><button onClick={handleClick}>Update</button></div>);
};
Now you can be sure that all your states will be synchronized, and you have total control over them.
Posted on April 18, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.