React hooks 中的多个提供者和路由器

Bri*_*bbs 0 reactjs react-router react-router-dom react-hooks

我在 React hooks 中使用多个上下文和减速器。

这是我的 App.js 文件

import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";

import Map from "./components/Map";
import Header from "./components/Header";
import Signup from "./components/Auth/Signup";
import Login from "./components/Auth/Login";
import UserList from "./components/User/UserList";

import "mapbox-gl/dist/mapbox-gl.css";

import { ApolloProvider } from "react-apollo";
import { ApolloClient } from "apollo-client";
import { WebSocketLink } from "apollo-link-ws";
import { InMemoryCache } from "apollo-cache-inmemory";
import { default as keysConfig } from "./keys.config";
import AuthProvider from "./providers/authProvider";
import withRoot from "./providers/withRoot";
import PageContent from "./pages/pageContent";
import ProtectedRoute from "./routePermissions/ProtectedRoute";
import AdminRoute from "./routePermissions/AdminRoute";
import PinProvider from "./providers/pinProvider";
import UserProvider from "./providers/userProvider";

const wsLink = new WebSocketLink({
  uri: `${keysConfig.WssBaseUrl}/graphql`,
  options: {
    reconnect: true
  }
});

const client = new ApolloClient({
  link: wsLink,
  cache: new InMemoryCache()
});

const App = () => {
  return (
    <Router>
      <ApolloProvider client={client}>
        <AuthProvider>
          <PageContent>
            <Header />
            <Switch>
              <PinProvider>
                <ProtectedRoute exact path="/" component={Map} />
              </PinProvider>
              <Route exact path="/login" component={Login} />
              <Route exact path="/signup" component={Signup} />
              <UserProvider>
                <AdminRoute exact path="/userlist" component={UserList} />
              </UserProvider>
            </Switch>
          </PageContent>
        </AuthProvider>
      </ApolloProvider>
    </Router>
  );
};

export default withRoot(App);
Run Code Online (Sandbox Code Playgroud)

我正在使用多个上下文和减速器。它让我使用多个提供商。但我想使用特定路线的提供者。

当我像代码片段一样使用路由时,ProtectedRoute 不起作用。

我希望有人帮助我解决这个问题。您可以为我提供如何更有效地组合反应钩子中的多个上下文和减速器的好方法。

sky*_*yer 7

[UPD] 请注意,问题已在 React Router 5 中提出并已给出答案。对于 v6,不再允许拥有某些东西,除非<Route>作为<Switch>

<Switch>适用于第一级儿童。它并不关心它是<Route><Provider>。因此,您需要调整代码,将提供程序移动到组件内部或仅利用render()以下变体Route

<Switch>
  <ProtectedRoute 
    exact 
    path="/" 
    render={(...params) => 
      <PinProvider><Map {...params} /></PinProvider>
    } 
  />
  <Route exact path="/login" component={Login} />
  <Route exact path="/signup" component={Signup} />
  <AdminRoute 
    exact 
    path="/userlist" 
    render={(params) => 
      <UserProvider><UserList {...params} /></UserProvider>
    } 
  />
</Switch>
Run Code Online (Sandbox Code Playgroud)

应该可以正常工作