React Native, How to use Redux store after dispatching in UseEffect?

Viewed 450

I have a react-native functional component that uses UseEffect to dispatch an action to the Redux store to update a field. After the field is updated, I would like the component to use the data to decide whether to show the data or navigate away.

const myScreen = props => {

    const fieldFromStore = useSelector(state=> state.mystore.myfield)

    useEffect(
      ()=>{
          dispatch(actionThatWillUpdateMyField)
          if (fieldFromStore == Something){
                props.navigation.navigate('NextPage')
             } //else just render the rest of the screen
          }, [])

    return (
            <View> 
                  <Text> {fieldfromStore}</Text>
            <View>)

The problem is the fieldFromStore in useEffect will always be null under effect as during that render of useEffect the store has not been updated yet.

Am I violating some sort of best practice here? How can I dispatch an action to update Store and then use that data to then determine how the page is rendered?

Thank you very much for the help.

2 Answers

Use a 2nd useEffect() block to handle the field change. The 2nd block should have fieldFromStore as a dependancy, so it will react to changes in the field:

const myScreen = props => {

  const fieldFromStore = useSelector(state => state.mystore.myfield)

  useEffect(() => {
    dispatch(actionThatWillUpdateMyField)
  }, [])

  useEffect(() => {
    if (fieldFromStore === Something) {
      props.navigation.navigate('NextPage')
    } //else just render the rest of the screen
  }, [fieldFromStore, props.navigation])

  // ...
}

You can use the dependency array of useEffect to control which selectors will cause your function to run again. So, instead of the empty array at the tail of your useEffect, use [ fieldFromStore ]. Full function below for clarity's sake

   useEffect(()=> {
      dispatch(actionThatWillUpdateMyField)
      if (fieldFromStore == Something) {
          props.navigation.navigate('NextPage')
      } //else just render the rest of the screen
   }, [ fieldFromStore ]);

The 'best practices' this might violate is that it will dispatch your action again when the selector changes. One way around this would be to dispatch the action before you navigate to the component you're on, and then a re-render here would be cleaner.

Related