1

I'm comming from a ReactJS background. There, I use useEffect to keep the state updated in my components. Whenever I mount them, I make an API request and show the updated state.

I'm now developing for React Native and using React Navigation. In React Navigation, screens aren't unmounted when the user navigate to another screen, so useEffect won't always fetch the API when a user comes back to a screen that was previous rendered.

Reading the React Navigation documentation, I see they have a useFocusEffect hook, which is called everytime a screen comes back in focus.

Their hook, however, seems to have a big boilerplate to replicate in each screen I need to always fetch updated data:

useFocusEffect(
  React.useCallback(() => {
    let isActive = true;

    const fetchUser = async () => {
      try {
        const user = await API.fetch({ userId });

        if (isActive) {
          setUser(user);
        }
      } catch (e) {
        // Handle error
      }
    };

    fetchUser();

    return () => {
      isActive = false;
    };
  }, [userId])
);

I tried to create my custom hook based using their useFocusEffect hook, but since the hook is not in the screen, I came into a problem of the hook not being called.

So my question is, what's the best way to keep my React Native state in sync with my backend and avoid unnecessary requests?

I'm used to Redux, so any solution that uses Redux is also appreciated. I just don't want to add to much complexity to Redux.

Thanks

Jared Smith
  • 19,721
  • 5
  • 45
  • 83
Otavio Bonder
  • 1,789
  • 4
  • 17
  • 35
  • I've edited your question to remove the request for offsite resources as doing so is off-topic. – Jared Smith Nov 20 '20 at 18:42
  • Doest this answer your question? https://stackoverflow.com/questions/60182942/useeffect-not-called-in-react-native-when-back-to-screen – Thales Kenne Nov 20 '20 at 18:45
  • Hi @ThalesKenne actually no. I know `useEffect` won't be called and why, and I also know a solution for it. My question is about how is the best way to keep states updated between React Native and backend – Otavio Bonder Nov 20 '20 at 18:47
  • Yes, I understand that. But in your post you're suggesting that you want to use useEffect to fetch from your API every time the screen is focused, which the question I mentioned solves. In that question, I'd actually go for the second (the most voted one) answer, rather than the accepted one :) It looks cleaner – Thales Kenne Nov 20 '20 at 18:52

1 Answers1

0

Despite my comments above, I like to keep my Redux updated with the data I just sent to my backend.

So what I often do, using Redux, is something along these lines:

const createPostAction = (post) => {
  return async (dispatch) => {
    try {
      const response = await sendToApi(post);
      return dispatch({
        type: SEND_POST_SUCCESS,
        payload: post
      })
    } catch (error){
      return dispatch({
       type: SEND_POST_FAIL
      })
    } 
  }
}

This will keep my store up to date with my backend, since it will save the new post to the store if it succeeds and wont incur any extra requests to keep it up to date. If it ever goes out of sync, your next app open should fetch from the api and start the cycle over.

Thales Kenne
  • 2,705
  • 1
  • 12
  • 26
  • This is a good solution. My problem is that I can't rely on the state stored in the redux state, because my customer can also use our platform thru the PC. I think I'll go with your suggestion of using the `useIsFocused`. Thanks – Otavio Bonder Nov 20 '20 at 19:20
  • Well, yeah. In that case you will need a connection to keep things up to date. Take a look at Socket.IO or any other websocket solution. You could just setup listeners and then keep your state up to date everywhere without actually "making requests" – Thales Kenne Nov 20 '20 at 19:41