I have a nested tabs navigator inside a stack navigator.
- When I navigate from Tab Screen A to Stack Screen B, B's useEffect is called, all good.
- When I navigate from Stack Screen C to also Stack Screen B, B's useEffect is NOT called. I dont understand why. -I am able to navigate to Screen B from both Screens, thats not the problem. I also am able to pass params. The only thing is just the useEffect is not called when coming from C, coming from A works fine.
I use in both cases same:
<Button title="goTo" onPress={() => props.navigation.navigate('SearchResults', {id: id})}/>
I also tried to use useIsFocused and useFocusEffect, but its also not called when I navigate from stack screen C. What am I doing wrong?
EDIT: It seems that the problem is with navigating to Screen C (from which I try to navigate to Screen B (that doesnt mount) is that I defined it in the header of Tab Navigator. If I wouldnt, I could navigate to C and C would mount. But I dont understand why that is or what to do. So In my code : When I navigate from NotificationsScreen to SearchResultsScreen, SearchScreen wont mount (as it seems its because I access NotificationsScreen from header of tabs navigator)
const MyTabs = (props) => {
return (
<Tab.Navigator
screenOptions={{
headerRight: (props) => (
<TouchableOpacity onPress={() => navigation.navigate("Notifications")}>
<Icon name="notifications"/>
</TouchableOpacity>
)
}}
>
<Tab.Screen
name="Home"
component={HomeScreen}
/>
<Tab.Screen
// when I navigate from SearchScreen to SearchResultsScreen, SearchResultsScreen useEffect is called
name="Search"
component={SearchScreen}
/>
</Tab.Navigator>
);
}
const MyStack = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Tabs">
{(props) => <MyTabs {...props} />}
</Stack.Screen>
<Stack.Screen
name="SearchResults"
component={SearchResultsScreen}
/>
<Stack.Screen
name="Notifications"
component={NotificationsScreen}
// when I navigate from NotificationsScreen to SearchResultsScreen, SearchResultsScreen useEffect is NOT called
/>
</Stack.Navigator>
CodePudding user response:
You can use in Notifications component
navigation.replace("SearchResults", null, null)
CodePudding user response:
because Stack screen B component is mounted when you first navigate to it and it calls useEffect, then you navigate to screen C, here B is not unmounted that's why when you navigate to Screen B again it is already mounted so useEffect does not executes. you just need to unmount Screen B like following
useEffect(()=>{
//useEffect stuff on mount
return () => {
// on component unmount.
}
},[])
CodePudding user response:
use **useFocusEffect**
on screen B to rerender every time the screen is focused
Here is the link https://reactnavigation.org/docs/use-focus-effect/
import { useFocusEffect } from '@react-navigation/native';
function Profile({ userId }) {
const [user, setUser] = React.useState(null);
useFocusEffect(
React.useCallback(() => {
const unsubscribe = API.subscribe(userId, user => setUser(user));
return () => unsubscribe();
}, [userId])
);
return <ProfileContent user={user} />;
}