Reputation: 10581
Let's say I have this screen:
And when the user clicks on the white tooltip, it redirects to another screen. Sometimes the app lags a little bit, and clicking on the tooltip takes like ~2s to see the screen change. The problem is, during those 2s, the user taps again on this tooltip to make it happen.
And the result I get is that there are two instances of the new screen in my StackNavigator. What I mean is that I see my new screen, but when I click on "Back" I don't return to this 'Hitchhiking Map' screen, but to another instance of that same screen.
If I clicked 5 times on the callout during those 2s, then I need to click 5 times "Back" to return to the Map screen. Any way to prevent that? To put only one instance into the StackNavigator?
I am using React Navigation, more precisely a StackNavigator. Here's my code:
The "click on tooltip" part:
<MapView.Marker
onCalloutPress={() => this.props.navigation.navigate('spotDetails', { spotId: marker.id })}
/>
My screens:
const HMapNavigator = StackNavigator({
HMap: { screen: HMapViewContainer },
spotDetails: { screen: SpotDetailsViewContainer },
});
Upvotes: 4
Views: 8581
Reputation: 940
Here is a hook that prevents navigating when the screen is not in focus. useIsFocused
comes from react-navigation
export const useRootNavigation = (): NavigationProp<RootStackParamList> & PushFunction => {
const isFocused = useIsFocused();
const navigation = useNavigation<NavigationProp<RootStackParamList> & PushFunction>();
const push = useCallback<PushFunction['push']>(
(...args) => {
if (isFocused) {
navigation.push(...args);
}
},
[navigation, isFocused],
);
return { ...navigation, push };
};
Upvotes: 0
Reputation: 23
In versions 1.x of React Navigation, if you specify an identifier the navigation action will be executed only once. E.g.:
navigate({ routeName: 'someScreen', key: 'someScreen', params: { someParam: 'someValue' } })
More information: https://gist.github.com/vonovak/ef72f5efe1d36742de8968ff6a708985
In versions 2.x and 3.x this is a default functionality.
More info: https://reactnavigation.org/docs/en/navigation-key.html
Upvotes: 0
Reputation: 966
Save if its opening to control the navigation
constructor (props) {
super(props)
this.state = {
opening: false
}
}
Create a function to control de navigation
_open (campaign) {
if (!this.state.opening) {
this.props.navigation.navigate('Campaign', {campaign})
this.setState({ opening: true })
setTimeout(() => {
this.setState({ opening: false })
}, 1000)
}
}
Call this func from your onpress
<TouchableHighlight underlayColor='transparent' onPress={this._open.bind(this, campaign)}>
Upvotes: 0
Reputation: 2531
There are many ways how to overcome double navigations.
My solution is adding a key
property in navigate object:
this.props.navigation.navigate({ key: 'AnotherScreen', routeName: 'AnotherScreen', params: { ... }})}
Upvotes: 5
Reputation: 496
The issue of multiple navigations has been reported and there is more detail here.
react-navigation (v1.0.0-beta.7) is in beta and still being built, so until this feature is implemented, you will have to handle the debounce manually.
options
onPress
logic or in the action if you are using reduxlodash provides a useful debounce utility, if you are looking for one.
Upvotes: 7