繁体   English   中英

React Router V5 在路由中使用上下文变量的最佳方式

[英]React Router V5 best way to use context variable in route

在我的应用程序中,我定义了我的路线,如下所示:

        <BrowserRouter>
          <Header />
          <div className="App">
            <Switch>
              <Route exact path="/">
                <Redirect to="/home" />
              </Route>
              <Route exact path={["/home", "/"]} component={Home} />
              <Route path="/account/:id" render={(props: RouteComponentProps<any>) => <Account {...props} />} />
              <Route component={NotFound} />
            </Switch>
          </div>
        </BrowserRouter>

我想知道的是,这可能很棘手,如果我希望我的路线有一个来自我的上下文的前缀,即变量,我将如何做到这一点,但扭曲的是变量来自 api 响应?

那么如果我想要路由/contextVariable/homecontextVariable来自 api 响应并存储在上下文值中,我知道如何将该变量带入组件但路由将如何处理它,即不是/undefined/home作为响应是否需要在插入路由之前完成?

有任何想法吗?

我曾经做过一个有类似要求的项目。 在那里,我没有声明动态路由,而是从 state 获取了一个路由数组,该数组是一个 object 数组,包含组件、路径和一些其他参数。 默认情况下,我添加了初始登录页面和未找到页面:

const [routes, setRoutes] = React.useState([
{
 component: HomeComponent,
 path: '/',
},
{
 component: NoMatchPage,
 path: '*',
}
])

然后我在 useEffect 块中有请求,它将像这样更新这个 state:

React.useEffect(()=>{
 // call api()
 const oldRoutes = routes;
 const noMatchPage = oldRoutes.pop();
 const newRoutes = [...oldRoutes, 
    responseFromApi.map(
     routeItem => 
        ({
          component: ComponentName, 
          path: routeItem.path
        })
     ), noMatchPage]
 setRoutes(newRoutes)
},[])

编辑

抱歉,我忘记了主要部分,这是 Route 渲染的方式:

<Switch>
    {
      routes.map(routeItem =>
        <Route path={routeItem.path} component={routeItem.component} />
      )
    }
</Switch>

此外,如果您想避免 useEffect 中的额外代码,您可以简单地执行以下操作:

React.useEffect(()=>{
 // call api()
 setRoutes(responseFromApi.map(
     routeItem => 
        ({
          component: ComponentName, 
          path: routeItem.path
        })
     ))
},[])

接着

<Switch>
    <Route exact path={["/home", "/"]} component={Home} />
    {
      routes.map(routeItem =>
        <Route path={routeItem.path} component={routeItem.component} />
      )
    }
    <Route component={NotFound} />
</Switch>

如果您想使用 React Context 执行此操作,那么这是我建议的模式。 创建一个包含 API 逻辑的 React 上下文,以获取“基本路径”并将其公开给消费者。 消费者将采用提供的“基本路径”值并将其添加到所有链接目标和路由路径。

例子:

BasePathProvider

import { createContext, useContext } from "react";

const BasePath = createContext({
  basepath: ""
});

const BasePathProvider = ({ children }) => {
  ... logic to fetch basepath ...

  return (
    <BasePath.Provider value={{ basepath }}>
      {children}
    </BasePath.Provider>
  );
};

const useBasePath = () => useContext(BasePath);

Header

const Header = () => {
  const { basepath } = useBasePath();

  return (
    ...
    <Link to={`${basepath}/`}>Home</Link>
    <Link to={`${basepath}/account/${/* some id value */}`}>
      Account
    </Link>
    ...
  );
};

应用程序

function App() {
  return (
    <div className="App">
      <Header />
      <BasePath.Consumer>
        {({ basepath }) => (
          <Switch>
            <Redirect from={`${basepath}/`} exact to={`${basepath}/home`} />
            <Route path={`${basepath}/home`} component={Home} />
            <Route path={`${basepath}/account/:id`} component={Account} />
            <Route component={NotFound} />
          </Switch>
        )}
      </BasePath.Consumer>
    </div>
  );
}

index.js

import { BrowserRouter as Router } from "react-router-dom";
import BasePathProvider from "../path/to/BasePathProvider";

...

<Router>
  <BasePathProvider>
    <App />
  </BasePathProvider>
</Router>

编辑 react-router-v5-best-way-to-use-context-variable-in-route

注意:您可能还希望/需要实现“加载” state 以有条件地渲染BasePathProvider组件的children组件,直到获取基本basepath值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM