I know that one of the fixed rules in React is that you cannot execute any hooks inside methods in a functional component or even inside other hooks like the useEffect hook. It must be executed in the body of the component itself.
So today while working on a quiz app, I ran into a situation where, after passing a screen on the stack navigator, I want to go back to that screen again by clicking on the back button. But this time, I want to modify the info on the previous screen with data from a graphql query using the useQuery hook provided by Apollo Client.
I can detect if the previous screen is focus using the isFocused
property on the props. If it changes, then I will fetch data again using useQuery.
I can do this simply like so:
React.useEffect(() => {
//how do I fetch data from here using useQuery if React prohibits me to use useQuery here?
}, [props.isFocused]);
So that is my question, is there a way around this? I'll appreciate your response.
To go back to the previous page, pass -1 as a parameter to the navigate() function, e.g. navigate(-1) . Calling navigate with -1 is the same as hitting the back button.
The header bar will automatically show a back button, but you can programmatically go back by calling navigation. goBack() . On Android, the hardware back button just works as expected. You can go back to an existing screen in the stack with navigation.
This answer assumes that you are using react-navigation
to create your stack navigator in React Native app
The useQuery
hook in Apollo Client runs the query whenever the component is mounted. In 'react-navigation' when you navigate to the next screen in your stack the previous(current) screen does not unmount. So when you go back the component is already mounted and therefore useQuery
does not run.
To tackle this, we have to listen to the lifecycle events of react navigation. Most importantly, the focus
event. We can refetch the query when the focus event of react navigation is called.
const { loading, data, refetch } = useQuery(QUERY);
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
// This check is to prevent error on component mount. The refetch function is defined only after the query is run once
// It also ensures that refetch runs only when you go back and not on component mount
if (refetch) {
// This will re-run the query
refetch();
}
});
return unsubscribe;
}, [navigation]);
This is how we ensure that the query gets called every time the screen is opened, in our react native apps.
Found this question with a similar problem on reactjs, where I loaded a page with data then went to another page to add a document to the database then on completion goes back to the original page.
Changing the default fetchPolicy
to network-only
ensure I was always getting the latest data available.
const { loading: loadingData, error, data } = useQuery(GetData, {
fetchPolicy: "network-only"
reference: https://www.apollographql.com/docs/react/data/queries/#setting-a-fetch-policy
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With