Instantly share code, notes, and snippets.
Created
March 4, 2017 22:04
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save NigelEarle/1832bd7dbb2ea9e13aed932dec3618f7 to your computer and use it in GitHub Desktop.
react-navigation redux example from `react-navigation/examples/Redux-Example`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @flow | |
*/ | |
import React from 'react'; | |
import { | |
AppRegistry, | |
AsyncStorage, | |
Button, | |
StyleSheet, | |
Text, | |
View, | |
} from 'react-native'; | |
import { | |
NavigationActions, | |
addNavigationHelpers, | |
StackNavigator, | |
} from 'react-navigation'; | |
import { | |
Provider, | |
connect, | |
} from 'react-redux'; | |
import { | |
createStore, | |
combineReducers, | |
} from 'redux'; | |
import { | |
persistStore, | |
autoRehydrate, | |
} from 'redux-persist'; | |
const ProfileScreen = ({ navigation }) => ( | |
<View style={styles.container}> | |
<Text style={styles.welcome}> | |
Profile Screen | |
</Text> | |
</View> | |
); | |
ProfileScreen.navigationOptions = { | |
title: 'Profile', | |
}; | |
const LoginScreen = ({ navigation }) => ( | |
<View style={styles.container}> | |
<Text style={styles.welcome}> | |
Screen A | |
</Text> | |
<Text style={styles.instructions}> | |
This is great | |
</Text> | |
<Button | |
onPress={() => navigation.dispatch({ type: 'Login' })} | |
title="Log in" | |
/> | |
</View> | |
); | |
LoginScreen.navigationOptions = { | |
title: 'Log In', | |
}; | |
const LoginStatusMessage = connect(state => ({ | |
isLoggedIn: state.auth.isLoggedIn, | |
}))(({ isLoggedIn, dispatch }) => { | |
if (!isLoggedIn) { | |
return <Text>Please log in</Text>; | |
} | |
return ( | |
<View> | |
<Text style={styles.welcome}> | |
{'You are "logged in" right now'} | |
</Text> | |
<Button | |
onPress={() => dispatch(NavigationActions.navigate({ routeName: 'Profile' }))} | |
title="Profile" | |
/> | |
</View> | |
); | |
}); | |
const AuthButton = connect(state => ({ | |
isLoggedIn: state.auth.isLoggedIn, | |
}), dispatch => ({ | |
logout: () => dispatch({ type: 'Logout' }), | |
login: () => dispatch(NavigationActions.navigate({ routeName: 'Login' })), | |
}))(({ logout, login, isLoggedIn }) => ( | |
<Button | |
title={isLoggedIn ? 'Log Out' : 'Log In'} | |
onPress={isLoggedIn ? logout : login} | |
/> | |
)); | |
const MainScreen = () => ( | |
<View style={styles.container}> | |
<LoginStatusMessage /> | |
<AuthButton /> | |
</View> | |
); | |
MainScreen.navigationOptions = { | |
title: 'Home Screen', | |
}; | |
const AppNavigator = StackNavigator({ | |
Login: { screen: LoginScreen }, | |
Main: { screen: MainScreen }, | |
Profile: { screen: ProfileScreen }, | |
}); | |
const AppWithNavigationState = connect(state => ({ | |
nav: state.nav, | |
}))(({ dispatch, nav }) => ( | |
<AppNavigator navigation={addNavigationHelpers({ dispatch, state: nav })} /> | |
)); | |
const initialNavState = { | |
index: 1, | |
routes: [ | |
{ key: 'InitA', routeName: 'Main' }, | |
{ key: 'InitB', routeName: 'Login' }, | |
], | |
}; | |
const initialAuthState = { isLoggedIn: false }; | |
const AppReducer = combineReducers({ | |
nav: (state = initialNavState, action) => { | |
if (action.type === 'Login') { | |
return AppNavigator.router.getStateForAction(NavigationActions.back(), state); | |
} | |
if (action.type === 'Logout') { | |
return AppNavigator.router.getStateForAction(NavigationActions.navigate({ routeName: 'Login' }), state); | |
} | |
return AppNavigator.router.getStateForAction(action, state); | |
}, | |
auth: (state = initialAuthState, action) => { | |
if (action.type === 'Login') { | |
return { ...state, isLoggedIn: true }; | |
} | |
if (action.type === 'Logout') { | |
return { ...state, isLoggedIn: false }; | |
} | |
return state; | |
}, | |
}); | |
class ReduxExampleApp extends React.Component { | |
store = createStore(AppReducer, undefined, autoRehydrate()); | |
componentDidMount() { | |
persistStore(this.store, { storage: AsyncStorage }); | |
} | |
render() { | |
return ( | |
<Provider store={this.store}> | |
<AppWithNavigationState /> | |
</Provider> | |
); | |
} | |
} | |
const styles = StyleSheet.create({ | |
container: { | |
flex: 1, | |
justifyContent: 'center', | |
alignItems: 'center', | |
backgroundColor: '#F5FCFF', | |
}, | |
welcome: { | |
fontSize: 20, | |
textAlign: 'center', | |
margin: 10, | |
}, | |
instructions: { | |
textAlign: 'center', | |
color: '#333333', | |
marginBottom: 5, | |
}, | |
}); | |
AppRegistry.registerComponent('ReduxExample', () => ReduxExampleApp); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment