React - Manage many state updates

yacinec_dev

Yacine C

Posted on April 18, 2023

React - Manage many state updates

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>);
};
Enter fullscreen mode Exit fullscreen mode

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>);
};
Enter fullscreen mode Exit fullscreen mode

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>);

};
Enter fullscreen mode Exit fullscreen mode

Now you can be sure that all your states will be synchronized, and you have total control over them.

πŸ’– πŸ’ͺ πŸ™… 🚩
yacinec_dev
Yacine C

Posted on April 18, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

What was your win this week?
weeklyretro What was your win this week?

November 29, 2024

Where GitOps Meets ClickOps
devops Where GitOps Meets ClickOps

November 29, 2024