包装React Antive应用程序与上下文提供商



我一直在遵循一些简单的教程(完整的工作源代码),以获取如何使用React的上下文以及在我的React Antive App中处理身份验证的想法。

此示例正在使用状态组件来查看和处理组件本身中的应用程序,例如在SignInScreen.js中:

/* SignInScreen.js */
export default class SignInScreen extends React.Component {
    static navigationOptions = {
        title: 'Please sign in',
    };
    _signInAsync = async (saveToken) => {
        saveToken()
            .then((data) => {
                // ROUTE USER TO "PROTECTED" PART OF THE APP
                this.props.navigation.navigate('App');
            })
            .catch((error) => {
                this.setState({ error })
            })
    };
    render() {
        return (
            <View style={styles.container}>
                <MyContext.Consumer>
                    {context => ((
                        <Button title="Sign in!" onPress={() => this._signInAsync(context.saveToken)} />
                    ))}
                </MyContext.Consumer>
            </View>
        );
    }
};

我试图将此组件转换为函数组件,并将逻辑中的签名移动到我的上下文提供商中:

/* 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>
        );
    }
}

当我尝试重定向用户时,当我按"登录"按钮时,我的提供商错误(this.props.navigation.navigate('App');),因为this.props.navigation不存在。

据我了解,

这是因为我没有在上下文中正确包装我的应用程序。

这是我的主要App.js文件:

/* 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

/* 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',
  }
));

AuthNavigatorAppTabNavigator仅包含createStackNavigator(),其中定义了我的屏幕。)

我的问题是:如何将此应用程序包装在我的上下文中,以便上下文提供商始终了解navigation Prop,因此我可以处理登录和外出,并从上下文提供商本身将用户与用户进行路由?

我通过使用NavigationActions解决了此问题,非常有用的内置模块为此目的而设计。

相关内容

  • 没有找到相关文章

最新更新