React Redux | local state updating before global redux state

I’m trying to create a page that contains a form that when submitted displays a message.

  • When this form is submitted a message is shown depending on what was in the form.
  • The message is created by dispatching the contents of the form to my redux action, which does some logic then updates my redux store via my reducer.
  • The frontend then checks the store for the message via useEffect(). However it only checks for the message based on a local state variable that keeps track of whether the form was clicked (so as to stop infinite re-renders).

Here is what I’ve done so far

import reduxAction from "somewhere"

function page() {
    const reduxState = useSelector((state) => state.someGlobalState);
    const [localIndicator, setLocalIndicator] = useState(false); // tracks if form was submitted
    const [message, setMessage] = useState("")

    const onSubmit = async(formData) => {
        dispatch(reduxAction(formData))
        setLocalIndicator(true) // update the local indicator when the form is clicked
    }

    useEffect( () => {
        /* After I click the form, the local indicator updates to true
           so the message is updated. THE ISSUE IS the reduxState has not yet been updated!
           By the time it updates, this has already happened and so im displaying the old message
           not the new one
        */
        if (setLocalIndicator === true){
            setMessage(reduxState.message)
            setLocalIndicator(false) // to prevent infinite re-renders
        }
    })

    return(
        <Form onSubmit=onSubmit>
            ...
        {message}
    )


}

Currently it’s not working because after I submit the form and dispatch the form data, the local state indicators update BUT the redux state does not update before useEffect() runs and so the form is re-rendered too early (useEffect() should only run after the redux state updates or the local state indicator should only update after the redux state updates.

Any help would be greatly appreciated.

>Solution :

You need to add reduxState.message and localIndicator to the dependencies array of useEffect so that it knows to update when that changes. Currently your useEffect will run on every render cycle, which is not ideal:

useEffect( () => {
        /* After I click the form, the local indicator updates to true
           so the message is updated. THE ISSUE IS the reduxState has not yet been updated!
           By the time it updates, this has already happened and so im displaying the old message
           not the new one
        */
        if (setLocalIndicator === true){
            setMessage(reduxState.message)
            setLocalIndicator(false) // to prevent infinite re-renders
        }
    },[localIndicator, reduxState.message])

Leave a Reply