FOLLOW ME: YouTube | dev.to | Twitter | Github | Medium | Reddit
Video
React Navigation Custom Navigation Drawer and Sharing State (with useContext)
Brief Intro
This is just a quick tutorial on how to create a custom drawer and then toggle some global state within that drawer that all of your components can listen to. It's also got some explanations of hooks in there, so please let me know if you have any questions on hooks.
Inspired by cool reddit.com/r/reactnative post: https://www.reddit.com/r/reactnative/comments/dcok40/passing_variables_between_a_drawer_and_a_screen/
SHUTUP, WHERES THE CODE
App.js
import React, {useState, createContext, useContext} from 'react';
import {StyleSheet, View, Text, StatusBar} from 'react-native';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import {createDrawerNavigator} from 'react-navigation-drawer';
import {createAppContainer} from 'react-navigation';
import {DrawerNavigatorItems} from 'react-navigation-drawer';
const BlueContext = createContext(true);
const HomeScreen = ({navigation}) => {
const {blue, setBlue} = useContext(BlueContext);
const bg = blue ? 'blue' : 'red';
return (
<>
<StatusBar barStyle="light-content" />
<View style={[styles.body, {backgroundColor: bg}]}>
<Text
onPress={() => {
navigation.openDrawer();
}}
style={styles.sectionTitle}>
Open Drawer
</Text>
<Text style={styles.sectionDescription}>
Click <Text style={styles.highlight}>Open Drawer</Text> and click the
button to change the color. Then come back here and check it out!
</Text>
<Text
onPress={() => {
setBlue(!blue);
}}
style={{fontSize: 22, color: 'white'}}>
Click me to toggle my color
</Text>
</View>
</>
);
};
const CustomDrawer = props => {
const {blue, setBlue} = useContext(BlueContext);
const textColor = blue ? 'blue' : 'red';
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text style={{fontSize: 32}}>Drawer</Text>
<Text
onPress={() => {
setBlue(!blue);
}}
style={{fontSize: 22, color: textColor}}>
Click me to toggle my color
</Text>
<DrawerNavigatorItems {...props} />
</View>
);
};
const DrawerNavigation = createDrawerNavigator(
{
Home: HomeScreen,
},
{
contentComponent: CustomDrawer,
},
);
const ApplicationContainer = createAppContainer(DrawerNavigation);
export default () => {
const [blue, setBlue] = useState(true);
return (
<BlueContext.Provider value={{blue, setBlue}}>
<ApplicationContainer />
</BlueContext.Provider>
);
};
const styles = StyleSheet.create({
body: {
flex: 1,
backgroundColor: Colors.black,
justifyContent: 'center',
padding: 16,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
color: Colors.white,
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
color: Colors.white,
},
highlight: {
fontWeight: '700',
},
});
package.json
{
"name": "ShareDrawerState",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"react": "16.9.0",
"react-native": "0.61.2",
"react-native-gesture-handler": "1.4.1",
"react-native-reanimated": "1.3.0",
"react-native-screens": "2.0.0-alpha.3",
"react-navigation": "4.0.10",
"react-navigation-drawer": "2.2.2"
},
"devDependencies": {
"@babel/core": "7.6.2",
"@babel/runtime": "7.6.2",
"@react-native-community/eslint-config": "0.0.5",
"babel-jest": "24.9.0",
"eslint": "6.5.1",
"jest": "24.9.0",
"metro-react-native-babel-preset": "0.56.0",
"react-test-renderer": "16.9.0"
},
"jest": {
"preset": "react-native"
}
}
π€π THANKS FOR READING π€π
If you liked the post, please be sure to give it a thumbs up, a heart, an upvote, a retweet, or whatever it is that the cool kids do these days. All my follow links are below if you're intersted in quick tutorials and explanations like this one.
π€ QUESTIONS | π COMMENTS | π CONCERNS | π© SUGGESTIONS
Let me know if you have any questions in the comments or if I could have done a better job explaining anything anywhere.
π COMMENTS
Why didn't you just use setParams?
I was expecting setParams to work, but apparently, you can't use setParams from your root navigator. I suppose I could have nested the Drawer Navigator, but I don't really like unnecessarily cluttering things up to fix errors. Any suggestions?
Most importantly,
π»π²π¨π»βπ»KEEP CODING, KEEP LEARNING, AND KEEP DOING!
Top comments (2)
This example is great! Thank you so much for making it available. I'm using react-navigation for the first time and it is hard to find working example of the Drawer Navigation/side menu that uses react-navigation v4, Context is the icing on the cake!
Iβm really glad it helped! Make sure to follow for much more of all kinds of content coming soon. Iβve been building a tool to help me go much faster and itβs just about ready for testing.
Stay tuned!