123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- ---
- id: third-party-react-context
- title: React Context API
- sidebar_label: React Context API
- ---
-
- ## React Context API
- React Context API provides a easy way to pass data through the component tree without having to pass props down
- manually at every level. You can find more about the Context API in [React documentation](https://reactjs.org/docs/context.html).
-
- You can use the React Context API with React Native Navigation with a limitation. In this example, we are going to create a screen which uses the Counter Context.
-
- :::important Limitation
- As RNN screens are not part of the same component tree, updating the values in the shared context does not trigger a re-render across all screens.
- However you can still use the React.Context per RNN screen component tree.
-
- If you need to trigger a re-render across all screens, there are many popular third party libraries such as
- [MobX](third-party-mobx.mdx) or Redux.
- :::
-
- ## Create a Counter context
-
- ```tsx
- // CounterContext.js
- import React from 'react
-
- // Declaring the state object globally.
- const initialCounterState = {
- count: 0
- }
-
- const counterContextWrapper = (component) => ({
- ...initialCounterState,
- increment: () => {
- initialCounterState.count += 1
- component.setState({ context: contextWrapper(component) })
- },
- decrement: () => {
- initialCounterState.count -= 1
- component.setState({ context: contextWrapper(component) })
- },
- })
-
- export const CounterContext = React.createContext({})
-
- export class CounterContextProvider extends React.Component {
- state = {
- context: counterContextWrapper(this)
- }
-
- render() {
- return (
- <CounterContext.Provider value={this.state.context}>
- {this.props.children}
- </CounterContext.Provider>
- )
- }
- }
- ```
-
- ## Register the screen
- When registering the screen that will be using the Counter Context, we need to wrap it
- with the Counter Context Provider we created earlier.
-
- ```tsx
- // index.js
- import { Navigation } from 'react-native-navigation
- import { CounterContextProvider } from './CounterContext
- import { App } from './App
-
- Navigation.registerComponent(
- 'App',
- () => props => (
- <CounterContextProvider>
- <App {...props} />
- </CounterContextProvider>
- ),
- () => App
- )
- ```
-
- ## Consuming the context
- You can consume the Counter Context any way you want such as `Provider.Consumer` or `React.useContext` like in the
- example below.
-
- ```tsx
- // App.js
- import React from 'react'
- import { Button, Text, View } from 'react-native'
- import { CounterContext } from './CounterContext'
-
- export const App = () => {
- // Using useContext API
- const { count, increment, decrement } = React.useContext(CounterContext)
-
- return (
- <View>
- <Text>{`Clicked ${count} times!`}</Text>
- <Button title="Increment" onPress={increment} />
- <Button title="Decrement" onPress={decrement} />
- </View>
- )
-
- // Using Context consumer
- return (
- <CounterContext.Consumer>
- {({ count, increment, decrement }) => (
- <View>
- <Text>{`Clicked ${count} times!`}</Text>
- <Button title="Increment" onPress={increment} />
- <Button title="Decrement" onPress={decrement} />
- </View>
- )}
- </CounterContext.Consumer>
- )
- }
- ```
|