Will a re-render of App() automatically re-render screens in navigation? - react-native

In the code below, if setStateVar is called but it doesn't affect which screens are displayed by the stacknavigator, will the displayed screen re-render or not? And if yes, is there a way to change this?
function App() {
const {stateVar, setStateVar} = useContext(VarContext);
return (
<NavigationContainer>
<Stack.Navigator>
{stateVar == null ? (
<>
<Stack.Screen options={{headerShown:false}} name="LoadingScreen" component={LoadingScreen} />
</>
) : (
<>
<Stack.Screen options={{headerShown: false}} name="SignUpScreen" component={SignUpScreen} />
</>
)
</Stack.Navigator>
</NavigationContainer>
);
}

Most likely it will. Even if you wrapped your components in React.memo(), if they use that context somewhere in their graph, they will rerender at the highest graph node that uses said context.

Related

Hide an element from a Navigation Container on a specific screen on React Native

My main App is the following
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" ... />
<Stack.Screen name="LogIn" ... />
<Stack.Screen name="Profile" ... />
</Stack.Navigator>
<NavBar />
</NavigationContainer>
);
}
It consists in some screens, and then a bottom navigation bar that is present in all the screens.
My question is, is there a way to hide the NavBar element in a specific screen or to specifically show it without having to manually put it in every screen?
I have tried:
Using the useRoute function to return nothing if the route name was an specific one
Manually putting the NavBar on every single screen (would solve it, but is not very efficient)

How to specify a default screen for react native stack navigator?

I want to navigate between two screens in my RN application: Daily and AllTodos. I want to make sure that when the navigator renders Daily by default. This is the code which I have used which accords the documentation :
const StackNavigator = ({component}) => {
return (
<NavigationContainer independent={true}>
<Stack.Navigator initialRouteName="Daily">
<Stack.Screen
name="Daily"
component={Daily}
options={{headerShown: false}}
/>
<Stack.Screen
name="AllTodos"
component={AllTodos}
options={{headerShown: false}}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
But still AllTodos page is rendered by default. Where am i going wrong?
You don't need to destructure the 'component' props. Take it off.
const StackNavigator = ({component}) // take off the component props => {

React Native Redux conditional rendering

I'm trying to render 2 different screens in my App based on the redux store status.
const App = () => {
return (
<Provider store={store}>
<NavigationContainer ref={navigationRef}>
{store.getState().auth.id ? (
<Home />
) : (
<Stack.Navigator screenOptions={HeaderStyles}>
<Stack.Screen
name='Splash'
component={Splash}
options={{ headerShown: false }}
/>
<Stack.Screen name='SignUp' component={SignUp} />
<Stack.Screen name='Login' component={Login} />
</Stack.Navigator>
)}
</NavigationContainer>
</Provider>
);
};
At startup store.getState().auth.id is undefined, so the app correctly shows the Splash screen. In this screen, I set the auth.id in the store but the App doesn't rerender and stays in the Splash screen. If I save any source file without changing anything, if forces a rerender and I get correctly routed to Home.
How can I force the ternary operator to be evalued again when the store changes?
At your file, store is imported from the file it is creating in, and not injected through props (mapState || useSelector).
Because React re-render built on changes in props || state, the component doesn't know it should render again.
The easy way to go around the issue is to declare the conditional part at the child component and inject the redux state properly.
<Provider store={store}>
<NavigationContainer ref={navigationRef}>
<Navigator />
</NavigationContainer>
</Provider>
....
const Navigator = () => {
let { id } = useSelector(state => state.auth)
return !!id ? (
<Home />
) : (
<Stack.Navigator screenOptions={HeaderStyles}>
<Stack.Screen
name='Splash'
component={Splash}
options={{ headerShown: false }}
/>
<Stack.Screen name='SignUp' component={SignUp} />
<Stack.Screen name='Login' component={Login} />
</Stack.Navigator>
)
}

React Native Navigation pass dynamic data when rendering

changeTheme(){
this.setState({darktheme:!this.state.darktheme})
}
render()
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} darkT={this.state.darktheme==true} />
<Stack.Screen name="Settings" component={SettingsScreen} changeTheme={this.changeTheme} darkT={this.state.darktheme==true} />
</Stack.Navigator>
</NavigationContainer>
);
}
In the settings page. I want to change the theme using this.props.changeTheme() it is supposed to change the state of the app and the whole app will re-render. But it doesn't work like that, the theme is not being changed. What am I doing wrong here?
When I log this.props.darkT it returns false even after I called the function changeTheme()
You can try this:
<Stack.Screen name="Settings">
{ () => <SettingsScreen darkT={!!this.state.darkTheme} changeTheme={this.changeTheme} /> }
</Stack.Screen>
In the Settings screen darkT and changeTheme will be available as props so you can access with this.props.darkT and this.props.changeTheme

React navigation stack navigator disable go back ability

How to disable ability to go back
I have a functional component
export default function App(){
createHomeStackNavigator = () =>
<Stack.Navigator screenOptions={{
headerShown: false
}}>
<Stack.Screen
name="Login"
component={Login}
/>
<Stack.Screen
name="Home"
children={createHomeTabNavigator}
/>
</Stack.Navigator>
return(
<NavigationContainer>
{createHomeStackNavigator()}
</NavigationContainer>
)
When user goes to Home, its onclick on Login component then he cant go back to the login by any swipe on ios, back button on Android and other ways
Probably you should use navigation.reset();