Skip to content

Instantly share code, notes, and snippets.

@imranariffin
Last active August 7, 2021 08:51
Show Gist options
  • Save imranariffin/fcc649a4f30a1f70dc6f50d1873c4832 to your computer and use it in GitHub Desktop.
Save imranariffin/fcc649a4f30a1f70dc6f50d1873c4832 to your computer and use it in GitHub Desktop.
React Native Private/Public Screen Pattern - Wrap the `@react-navigation/stack` to be auth aware (Note: replace `.` in file names with `/` to make more sense)
import AScreen from 'screens/A'
import BScreen from 'screens/B'
import MainScreen from 'screens/Main'
import SignInScreen from 'screens/SignIn'
import SignUpScreen from 'screens/SignUp'
import SomeNestedScreen from 'screens/SomeNested'
import StackNavigator from './stack-navigator'
const Navigations = () => {
return (
<>
<StackNavigator.Navigator initialRouteName='SignIn'>
<StackNavigator.PublicScreen name='SignUp' component={SignUpScreen} />
<StackNavigator.PublicScreen name='SignIn' component={SignInScreen} />
</StackNavigator.Navigator>
<StackNavigator.Navigator initialRouteName='Main'>
<StackNavigator.PrivateScreen name='Main' component={MainScreen} />
<StackNavigator.PrivateScreen name='A' component={AScreen} />
<StackNavigator.PrivateScreen name='B' component={BScreen} />
<StackNavigator.Navigator initialRouteName='SomeNestedScreen'>
<StackNavigator.PrivateScreen name='SomeNestedScreen' component={SomeNestedScreen} />
</StackNavigator.Navigator>
</StackNavigator.Navigator>
</>
)
}
export default Navigations
import Stack from './stack'
const PublicScreen = ({ component, name }) => {
return <Stack.Screen name={name} component={component} />
}
export default PublicScreen
import PrivateScreen from './private-screen'
import PublicScreen from './public-screen'
import Stack from './stack'
export {
Navigator: Stack.Navigator,
PrivateScreen,
PublicScreen,
}
import Login from 'screens/Login'
import Stack from './stack'
const PrivateScreen = ({ isAuthenticated, component, name, navigateToLogin }) => {
if (!isAuthenticated) {
navigateToLogin()
return null
}
return <Stack.Screen name={name} component={component} />
}
export default PrivateScreen
import { connect } from 'react-redux'
import someAuthSelectors from 'src/authentication/selectors'
import PrivateScreen from './component'
const mapStateToProps = (state) => {
return {
// Let redux determine the state of authentication
isAuthenticated: someAuthSelectors.getIsAuthenticated(state),
}
}
const mapDispatchToProps = (dispatch, { navigation }) => {
return {
navigateToLogin: dispatch(navigation.navigate('Login')),
}
}
export default connect(
mapStateToProps,
mapDispatchToProps,
)(PrivateScreen)
import { createStackNavigator } from '@react-navigation/stack'
const Stack = createStackNavigator()
export default Stack
@hbina
Copy link

hbina commented Apr 26, 2021

Its been a while since I've use React but it seems like you passed an undefined value in <Login ...>. Share some code?

@MeryemGh
Copy link

MeryemGh commented May 4, 2021

Thanks hbina for responding i've used another method to solve the problem , !

@abhiburk
Copy link

abhiburk commented Aug 7, 2021

I keep get error Error: A navigator can only contain 'Screen' components as its direct children (found 'undefined' for the screen 'Login')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment