How should the new context api work with React Native navigator?

react-native navigation context api
react native context api
react context store
react-native navigation redux
authcontext = react native
react-navigation example
react multiple contexts
dynamic context react

I created a multiscreen app using React Navigator following this example:

import {
  createStackNavigator,
} from 'react-navigation';

const App = createStackNavigator({
  Home: { screen: HomeScreen },
  Profile: { screen: ProfileScreen },
});

export default App;

Now I'd like to add a global configuration state using the new builtin context api, so I can have some common data which can be manipulated and displayed from multiple screens.

The problem is context apparently requires components having a common parent component, so that context can be passed down to child components.

How can I implement this using screens which do not share a common parent as far as I know, because they are managed by react navigator?

You can make it like this.

Create new file: GlobalContext.js

import React from 'react';

const GlobalContext = React.createContext({});

export class GlobalContextProvider extends React.Component {
  state = {
    isOnline: true
  }

  switchToOnline = () => {
    this.setState({ isOnline: true });
  }

  switchToOffline = () => {
    this.setState({ isOnline: false });
  }

  render () {
    return (
      <GlobalContext.Provider
        value={{
          ...this.state,
          switchToOnline: this.switchToOnline,
          switchToOffline: this.switchToOffline
        }}
      >
        {this.props.children}
      </GlobalContext.Provider>
    )
  }
}

// create the consumer as higher order component
export const withGlobalContext = ChildComponent => props => (
  <GlobalContext.Consumer>
    {
      context => <ChildComponent {...props} global={context}  />
    }
  </GlobalContext.Consumer>
);

On index.js wrap your root component with context provider component.

<GlobalContextProvider>
  <App />
</GlobalContextProvider>

Then on your screen HomeScreen.js use the consumer component like this.

import React from 'react';
import { View, Text } from 'react-native';
import { withGlobalContext } from './GlobalContext';

class HomeScreen extends React.Component {
  render () {
    return (
      <View>
        <Text>Is online: {this.props.global.isOnline}</Text>
      </View>
    )
  }
}

export default withGlobalContext(HomeScreen);

You can also create multiple context provider to separate your concerns, and use the HOC consumer on the screen you want.

Context API (react 16.3) · Issue #3297 · wix/react-native-navigation , I created a multiscreen app using React Navigator following this example: import { createStackNavigator, } from 'react-navigation'; const App  Due to the component based API of React Navigation 5.x, we have a much better alternative to screenProps which doesn't have these disadvantages: React Context. Using React Context, it's possible to pass data to any child component in a performant and type-safe way, and we don't need to learn a new API! #Themes. React Navigation 4.x had basic

This answer takes in consideration react-navigation package.

You have to wrap your App component with the ContextProvider in order to have access to your context on both screens.

    import { createAppContainer } from 'react-navigation'
    import { createStackNavigator } from 'react-navigation-stack'
    import ProfileContextProvider from '../some/path/ProfileContextProvider'

    const RootStack = createStackNavigator({
      Home: { screen: HomeScreen },
      Profile: { screen: ProfileScreen },
    });

    const AppContainer = createAppContainer(RootStack)    
    const App = () => {
      return (
      <ProfileContextProvider>
        <AppContainer />
      </ProfileContextProvider>);
    }

wix/react-native-navigation, new Context API introduce in react 16.3 with react-native-navigation? /how-​should-the-new-context-api-work-with-react-native-navigator  To finalize installation of react-native-gesture-handler, add the following at the top (make sure it's at the top and there's nothing else before it) of your entry file, such as index.js or App.js: import 'react-native-gesture-handler'; Now, you need to wrap the whole app in NavigationContainer.

If you want the detailed tutorial you could follow the below link : Visit : https://www.thelearninguy.com/simple-react-native-context-api-detailed

A very long answer would be as follows.

import React, {Component} from 'react';
import {Text, View, Button} from 'react-native';

//make a new context
const MyContext = React.createContext();

//create provider component
class MyProvider extends Component {
    state = {
        name: "The Learnin Guy",
        age: 50
    };
    increaseAge = () => {
        this.setState({
            age: this.state.age + 1
        });
    };

    render() {
        return (
            <MyContext.Provider
                value={{
                    state: this.state,
                    increaseAge: this.increaseAge
                }}
            >
                {this.props.children}
            </MyContext.Provider>
        );
    }
}

class Person extends Component {
    render() {
        return (
            <View>
                <Text>This is Person Component</Text>
                <MyContext.Consumer>
                    {(context) => (
                        <React.Fragment>
                            <Text>Name: {context.state.age}</Text>
                            <Text>Age: {context.state.age}</Text>
                            <Button title="IncreaseAge" onPress={context.increaseAge} />
                        </React.Fragment>
                    )}
                </MyContext.Consumer>
            </View>
        );
    }
}

class Family extends Component {
    render() {
        return (
            <View>
                <Text>This is Family Component</Text>
                <MyContext.Consumer>
                    {(context) => (
                        <React.Fragment>
                            <Text>Age: {context.state.age}</Text>
                        </React.Fragment>
                    )}
                </MyContext.Consumer>
                <Person/>
            </View>
        );
    }
}

class App extends Component {
    render() {
        return (
            <MyProvider>
                <View>
                    <Text>This is App Component</Text>
                    <MyContext.Consumer>
                        {(context) => (
                            <React.Fragment>
                                <Text>Age: {context.state.age}</Text>
                            </React.Fragment>
                        )}
                    </MyContext.Consumer>
                    <Family/>
                </View>
            </MyProvider>
        );
    }
}

export default App;

Courtesy - https://www.thelearninguy.com

Localization With React Navigation 4 and the Context API, Great work with adding support for React context API @guyca! to be the same on each screen, but it creates a new context for each screen. Does react-native​-navigation have a proper solution to the context API yet? React Navigation will automatically navigate to the Home screen when isSignedIn becomes true. This takes advantage of a new feature in React Navigation: being able to dynamically define and alter the screen definitions of a navigator based on props or state. The example shows stack navigator, but you can use the same approach with any navigator.

React-Native + Context API - Daniel Teles, Feeling curious, I took an afternoon to see how that would work. React Native 0.61; React Navigation 4; i18next 19 & react-i18next 10 (but you can that any components may access our new context to translate our content. Provides a way for your app to transition between screens where each new screen is placed on top of a stack. By default the stack navigator is configured to have the familiar iOS and Android look & feel: new screens slide in from the right on iOS, fade in from the bottom on Android. On iOS the stack navigator can also be configured to a modal

State management in React Native using context, What would you say if someone ask you to build an application with several React 16.3.0 was released and with it the brand new Context API was introduced. that will give you the main idea of how this context API works. For example, React Navigation's tab navigator takes care of handling the Android back button for you, while standalone components typically do not. Additionally, it is more difficult for you (as the developer) to perform actions such as "jump to this tab and then go to this screen" if you need to call into two distinct APIs for it.

NavigationContext, using context to manage application state in react native. some difficulty with React Native because of the quite complex API of React Navigation. So, here is a way devs could structure their context providers in react native: to the value receiving a new reference every time the component is rendered. React previously shipped with an experimental context API. The old API will be supported in all 16.x releases, but applications using it should migrate to the new version. The legacy API will be removed in a future major React version.

Comments
  • You can use Redux to manage you state.
  • Yes, thank you. I know about Redux, but supposedly the same thing can be done with the new Context api, so I'd like to do it with builtin features instead of adding an external package just for this.
  • i realise its a year late but i guess you could try doing this by creating a custom Navigator and passing the context providers when rendering the navigator, you can refer the doc for steps on how to create a custom navigator (reactnavigation.org/docs/en/custom-navigators.html). Please do revert is this works for you.
  • Redux is also another and a better way to do this.
  • You should add reasons why it’s a better as at the moment this comment is not very helpful.
  • @Dede, Thank you for your answer, but it is not completely addressing, how to use context with React Navigator, as asked in question
  • Sorry to discourage, as per my reading, I see passing state from one screen to another screen is the only feasible option and use this state, like navigation.state.params
  • what about if i wanted to inject the router's props.navigation to the context api ?
  • Ah this is the closest one I found yet. What happens if you are rendering through a switchNavigator?
  • This does not answer the question on how to use context with react navigation