Reputation: 350
On Screen A, there is a value to keep track of loading of a GraphQL mutation. I want to pass that loading value to Screen B. My problem is that when I try to pass that value as a param to Screen B using navigation.navigate(ScreenB, { loading })
, the value of loading does not update - it always remains as whatever the value was at the moment that navigation.navigate was invoked.
I know that setParams
updates the param for a given route, but it does not seem to apply to my use case because it does not alter the param between routes. Is there any way that the previous screen can dynamically set the param so that I can recuperate the changed value while on the current screen?
const ScreenA = (props) => {
const { data, loading } = useQuery(QUERY);
(
<View>
<Button onPress={() => navigation.navigate(ScreenB, { loading } }/>
</View>
)
}
const ScreenB = (props) => {
const screenALoading = navigation.getParam('loading');
return (
<Text>{loading}</Text>
)
}
Upvotes: 2
Views: 1629
Reputation: 350
giotskhada’s answer makes a lot of sense. Redux is a very useful way for solving this kind of issue by keeping a global state, and this kind of problem is a good example of how Redux provides a useful complement to Apollo.
That being said, I did not want to setup Redux for one small thing so I continued working on this problem, and I figured out a way to solve this without adding redux for those who are interested.
In order to update loading on Screen B after having switched from Screen A, I call navigation.navigate again with the updated value but only after having switched to ScreenB.
const [navigatedToScreenB, toggleNavigatedToScreenB] = useState<boolean>(false);
useEffect(() => {
if(navigatedToScreenB) {
navigation.navigate(ScreenB, { loading });
}
}, [loading])
Since I only want to do further navigations to ScreenB, if loading changes, it's important to add loading
as a dependency of useEffect.
And in the onPress function to switch to ScreenB I do:
onPress={() =>
{
toggleNavigatedToScreenB(true);
navigation.navigate(ScreenB, { toggleNavigatedToScreenB });
}
}
By passing toggleNavigatedToScreenB to ScreenB, I can alert ScreenA that I"m no longer on Screen B in order to stop the navigating when loading changes. If I were to change the screen in order to stop navigating to ScreenB. So for example in the back button of ScreenB, I’d put:
onPress={() =>
{
toggleNavigatedToScreenB(false);
navigation.goBack();
}
}
I admit it’s a lot more convoluted than redux, but I got it to work so I wanted to share this solution for anyone with the same problem.
Upvotes: 0
Reputation: 2452
You might want to consider adding some type of global state to your app, since it solves this problem and, as your app gets bigger, you might want to add it in the future anyways. I believe Redux is the best one, but you can use Context and react hooks to create your own. Afterwards, you can just set the state from the previous screen and read it in the current one.
Upvotes: 1