React Native Navigation pass dynamic data when rendering - react-native

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

Related

Render a nested Tab screen in a Stack Navigator

Seems it should be so simple but I can't figure it out. I have a nested Tab Navigator inside a Stack Navigator like so:
function App(){
const Main = () =>{
<Tab.Navigator initialRouteName={"Players"}>
<Tab.Screen name="Players" component={FindPlayers} />
<Tab.Screen name="Requests" component={MatchRequests} />
</Tab.Navigator>
}
....
return (
<NavigationContainer>
<Stack.Navigator initialRouteName={"Main"} >
<Stack.Screen name="Main" component={Main}/>
<Stack.Screen name="CourtPicker" component={CourtPicker}/>
</Stack.Navigator>
</NavigationContainer>
)}
It renders a blank screen with the Header that says "Main" instead of rendering the FindPlayers component.
My expectation is that I've defined an initial route Main which should render my Main component which is a Tab navigator, which should in turn render the Players component because I've defined the initialRouteName as such.
What am I doing wrong here?
according to Nesting navigators
Try :
<Stack.Screen name="Main" component={Main} options={{
headerShown: false,
}}/>

Right-to-left screen animation in React Native navigation

I'd like to have screen animations from right to left in React Native. I checked a lot in the internet but most of the examples are old and they are using StackNavigator differently and the configurations are also different. I think they are using an old version of React Navigation. I use version 6. I also tried as explained here in docs https://reactnavigation.org/docs/stack-navigator/#animations but it didn't worked in any way.
Could you please help? Here is my code:
const Tab = createBottomTabNavigator();
const Stack = createNativeStackNavigator();
function MainScreen() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="To Read" component={ToReadScreen} />
<Tab.Screen name="Have Read" component={HaveReadScreen} />
</Tab.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="ReadX"
component={MainScreen}
/>
<Stack.Screen
name="Settings"
component={SettingsScreen}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
So I am trying to configure the screen animation between main screen and setting screen.
Any help would be appreaciated. Thanks.
Assuming this is a recent react-navigation v6 version, use the animationTypeForReplace option:
<Stack.Screen
name="Settings"
component={SettingsScreen}
options={{
animationTypeForReplace: 'pop',
}}
/>
https://reactnavigation.org/docs/stack-navigator/#animationtypeforreplace
<Stack.Navigator initialRouteName='LoginPage' screenOptions={{ headerShown: false, animation: 'slide_from_right' }}>
you have to use animation props in Stack.Navigator in screenOptions

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 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();