React Native 6 - 在 App.js 中对用户进行身份验证和导航到适当堆栈的干净(和最新)方式

React Native 6 - Clean (and up-to-date) way to Authenticate and Navigate User to appropriate Stack in App.js

我一直在通过不使用版本 6 的课程学习 React Native,并且不推荐使用 Context / Provider 机制。

因此,我无法升级我的代码以使用最新的良好做法。

这是我正在尝试做的事情的概述。

const App = (props) => {
  const isAuth = true;

  return (
    <AuthProvider>
      <NavigationContainer>
        {isAuth && <MainStackScreens />}
        {!isAuth && <LoginStackScreens />}
      </NavigationContainer>
    </AuthProvider>
  );
};

基本上我想用对 AuthProvider 传达的状态的访问权限替换我的 isAuth 变量(并使用令牌!),我相信这就是它的目的。

阅读更多文档后,我意识到,由于 Provider,确实可以通过导入提供给任何子级的 Context 来访问整个应用程序的状态。但是,我不明白如何在 NavigationContainer 上的 App.js 中访问它。

你能帮忙吗?

一些额外的资源...

我的 Provider 是这样导入 App.js 的:

import { Provider as AuthProvider } from './context/AuthContext'; 

并这样定义:

    import createDataContext from "./createDataContext";
    import AsyncStorage from '@react-native-async-storage/async-storage';
    
    const authReducer = (state, action) => {
        switch(action.type) {
            case 'add_error': 
                return {...state, errorMessage: action.payload}
            case 'token_stored':
                return { errorMessage:'', token: action.payload}
            case 'logout':
                return { token:null, errorMessage:''}
            default:
                return state;
        }
    } ;
    
    const signup = (dispatch) => async ( {username, email, password}) => { // some code } ;
    
    
    const signin = (dispatch) => async ( {username, password}) => { // some code } ;
    
    
    export const { Provider, Context} = createDataContext(
        authReducer,
        {signin, signup},
        { token: null, errorMessage: '' }
    );

createDataContext 的定义如下:

import React, { useReducer } from "react";

export default (reducer, actions, defaultValue) => {
  const Context = React.createContext();

  const Provider = ({ children }) => {
    const [state, dispatch] = useReducer(reducer, defaultValue);

    const boundActions = {};
    for (let key in actions) {
      boundActions[key] = actions[key](dispatch);
    }

    return (
      <Context.Provider value={{ state, ...boundActions }}>
        {children}
      </Context.Provider>
    );
  };

  return { Context, Provider };
};

创建另一个屏幕

return (
    <AuthProvider>
      <NavigationContainer>
        <Screens />
      </NavigationContainer>
    </AuthProvider>
  );

Screens = () = >
// get auth from context
return (
    <>
        {isAuth && <MainStackScreens />}
        {!isAuth && <LoginStackScreens />}
    </>
  );