---
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>
  )
}
```
