Javascript 使用上下文提供程序包装React本机应用程序

Javascript 使用上下文提供程序包装React本机应用程序,javascript,reactjs,react-native,react-context,Javascript,Reactjs,React Native,React Context,我一直在遵循一些()来了解如何在我的React原生应用程序中使用React的上下文并处理身份验证 此示例使用有状态组件进行查看,并在组件本身内处理应用程序路由,例如: 和我的AppNavigator.js: /* AppNavigator.js */ import React from 'react'; import { createAppContainer, createSwitchNavigator } from 'react-navigation'; import AuthLoadin

我一直在遵循一些()来了解如何在我的React原生应用程序中使用React的上下文并处理身份验证

此示例使用有状态组件进行查看,并在组件本身内处理应用程序路由,例如:

和我的
AppNavigator.js

/* AppNavigator.js */

import React from 'react';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';

import AuthLoadingScreen from '../screens/AuthLoadingScreen';
import Auth from './AuthNavigator';
import App from './AppTabNavigator';


export default createAppContainer(createSwitchNavigator(
  {
    AuthLoading: AuthLoadingScreen,
    Auth,
    App,
  },
  {
    initialRouteName: 'AuthLoading',
  }
));
AuthNavigator
AppTabNavigator
仅包含
createStackNavigator()
,其中定义了我的屏幕。)

我的问题是:我如何用我的上下文包装这个应用程序,以便上下文提供商始终知道
导航
道具,这样我就可以处理从上下文提供商本身登录、注销和路由用户的问题?

我通过使用非常有用的内置模块来解决这个问题。

我通过使用,为此目的设计的非常有用的内置模块

/* SignInScreen.js - MODIFIED */

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

import { MyContext } from '../Provider';

export default const LoginScreen = () => {
  return (
    <View>
      <MyContext.Consumer>
        {context => {
          return (
            <Button
              onPress={() => context.signIn()}
              title="Sign In"
            />
          )
        }
      }
      </MyContext.Consumer>
    </View>
  )
};



/* Provider.js */

import React from 'react';
import { AsyncStorage } from 'react-native';

export const MyContext = React.createContext();

export default class MyProvider extends React.Component {
    constructor(props) {
      super(props);
      this.getToken = () => AsyncStorage.getItem('userToken');
      this.saveToken = () => AsyncStorage.setItem('userToken', 'abc');
      this.removeToken = () => AsyncStorage.removeItem('userToken');

      this.signIn = () => {
        this.saveToken()
          .then((data) => {
            // this.props.navigation DOES NOT EXIST!!! :(
            this.props.navigation.navigate('App');
          })
          .catch((error) => this.setState({ error }));
      };

      this.state = {
        token: '',
        signIn: this.signIn,
      };
    }

    componentWillMount() {
        AsyncStorage.getItem('userToken')
            .then((token) => {
                this.setState({ token })
            })
            .catch(error => {
                this.setState({ error })
            })
    }

    render() {
        return (
            <MyContext.Provider value={this.state}>
                {this.props.children}
            </MyContext.Provider>
        );
    }
}
/* App.js */

import React from 'react';
import { View } from 'react-native';

import MyContext from './Provider';
import AppNavigator from './navigation/AppNavigator';


export default class App extends React.Component {
  render() {
    return (
      <MyContext>
        <View>
          <AppNavigator />
        </View>
      </MyContext>
    );
  }
}
/* AppNavigator.js */

import React from 'react';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';

import AuthLoadingScreen from '../screens/AuthLoadingScreen';
import Auth from './AuthNavigator';
import App from './AppTabNavigator';


export default createAppContainer(createSwitchNavigator(
  {
    AuthLoading: AuthLoadingScreen,
    Auth,
    App,
  },
  {
    initialRouteName: 'AuthLoading',
  }
));