在使用 react-router 和 redux 时,Context Provider 应该嵌套在什么嵌套中?

At what nesting the Context Provider should be wrapped while using react-router and redux?

当我学习 React 时,我学会了创建一个 context.js 文件并将所有在整个组件树中使用的状态放入并使用上下文提供程序将根组件包装在 index.js 中,以便整个应用可以访问它们。

像这样

context.js

import React, { useState, useContex} from 'react';

const AppContext = React.createContext();

const AppProvider = (props) => {
  return (
    <AppContext.Provider value={{ isLoggedIn: props.isLoggedIn }}>
      {props.chidren}
    </AppContext.Provider>
  );
} 

export const useGlobalContext = () => {
  return useContext(AppContext);
};

index.js


ReactDOM.render(
  <React.StrictMode>
    <AppProvider>
      <App />
    </AppProvider>
  </React.StrictMode>,
  document.getElementById('root')
);

我使用 useGlobalContext 自定义挂钩来访问这些变量。

但是现在我在我的项目中使用了react-router 和redux。但是我仍然有必要对某些状态变量使用全局上下文。 问题是我无法弄清楚我应该在什么嵌套级别将 包装在我的 index.js 中而不影响 react-router 和 redux 的功能。

当前index.js

nst Routing = () => {
  console.log('store = ', store);
  return (
    <Provider store={store}>
      <PersistGate persistor={persistor} loading={Loading}>
        <Router>
          <React.StrictMode>
            <Header />
            <Switch>
              <Route exact path='/' component={App} />
              <Route path='/register' component={Register} />
              <Route path='/login' component={Login} />
              <Route path='/logout' component={Logout} />
              <Route path='/verify-email' component={VerifyEmail} />
            </Switch>
            <Footer />
          </React.StrictMode>
        </Router>
      </PersistGate>
    </Provider>
  );
};

ReactDOM.render(<Routing />, document.getElementById('root'));

提前致谢。

编辑:1

每个包装级别的错误消息

  1. 最外面

    const Routing = () => {
      console.log('store = ', store);
      return (
        <AppProvider>
          <Provider store={store}>
            <PersistGate persistor={persistor} loading={Loading}>
              <Router>
  
              </Router>
            </PersistGate>
          </Provider>
        </AppProvider>
      );
    };

错误信息 错误:在“Connect(AppProvider)”的上下文中找不到“store”。将根组件包装在 a 中,或者将自定义 React 上下文提供程序传递给连接选项并将相应的 React 上下文使用者传递给连接选项中的 Connect(AppProvider)。

  1. 一级嵌套
const Routing = () => {
  console.log('store = ', store);
  return (
    <Provider store={store}>
      <AppProvider>
        <PersistGate persistor={persistor} loading={Loading}>
          <Router>
            <React.StrictMode>
              <Header />
              <Switch>
                <Route exact path='/' component={App} />
                <Route path='/register' component={Register} />
                <Route path='/login' component={Login} />
                <Route path='/logout' component={Logout} />
                <Route path='/verify-email' component={VerifyEmail} />
              </Switch>
              <Footer />
            </React.StrictMode>
          </Router>
        </PersistGate>
      </AppProvider>
    </Provider>
  );
};

错误:没有错误,但反应路由器不工作。

  1. 内部路由器
const Routing = () => {
  console.log('store = ', store);
  return (
    <Provider store={store}>
      <PersistGate persistor={persistor} loading={Loading}>
        <Router>
          <AppProvider>
            <React.StrictMode>
              <Header />
              <Switch>
                <Route exact path='/' component={App} />
                <Route path='/register' component={Register} />
                <Route path='/login' component={Login} />
                <Route path='/logout' component={Logout} />
                <Route path='/verify-email' component={VerifyEmail} />
              </Switch>
              <Footer />
            </React.StrictMode>
          </AppProvider>
        </Router>
      </PersistGate>
    </Provider>
  );
};

错误:同一个路由器不工作,

编辑 2

这是我的 context.js 文件

import React, { useContext } from 'react';
import { connect } from 'react-redux';

// This file contains all state store variables that will be useful throughout the application.
// Thuis component wraps the whole component tree and provides a context to use these varaibles

const AppContext = React.createContext();

const AppProvider = (props) => {
  return (
    <AppContext.Provider
    // value={{ isLoggedIn: props.isLoggedIn }}
    >
      {props.chidren}
    </AppContext.Provider>
  );
};

const mapStateToProps = (state) => {
  return {
    isloggedIn: state.userLogin.isLoggedIn,
  };
};

export const useGlobalContext = () => {
  return useContext(AppContext);
};

export default connect(mapStateToProps, null)(AppProvider);

因为我在 context.js 里面使用 redux store,所以它必须在里面并且 .但是如果我把它放在里面,路由器将无法工作。

除了 可能 访问 state 对象和您的app/redux 连接中断。您确定 state.userLogin.isLoggedIn 有效吗?

为什么不用react-redux

提供的useSelector
const isloggedIn = useSelector(state => state.userLogin.isLoggedIn);

与将整个其他上下文提供程序添加到您的应用程序相比,它更简单且活动部件更少。

如果这是您在几乎每个组件中都要做的事情,您可以为您在每个组件中拉取的状态切片创建一个自定义挂钩。

import { useSelector } from 'react-redux';

const useCustomSelector = () {
  const isloggedIn = useSelector(state => state.userLogin.isLoggedIn);
  // pull other state

  return {
    isloggedIn,
    // return other state
  };
};

用法:

const { isloggedIn } = useCustomSelector();