如何将上下文 api 与反应路由器 v4 一起使用?

新手上路,请多包涵

我正在我的应用程序上尝试使用 React 16.3 中的新上下文 API 进行一些测试,但我不明白为什么我的重定向永远不起作用。

 <ContextA>
  <Switch>
    <Route exact path='/route1' component={ Component1 } />
    <ContextB>
      <Route exact path='/route2' component={ Component2 } />
      <Route exact path='/route3' component={ Component3 } />
    </ContextB>
    <Redirect from='/' to='/route1' />
  </Switch>
</ContextA>

我不想让我的 ContextB 可用于所有路线,只有 2 条和 3 条。我该怎么做?

原文由 vinicius sabadim 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 482
2 个回答

作为 对其他人的警告,接受的答案 并不像您对原始(非工作)概念所期望的那样真正起作用

 // This comes from the original question (doesn't work as-is!)
<ContextA>
  <Switch>
    <Route exact path='/route1' component={ Component1 } />
      <ContextB>
        <Route exact path='/route2' component={ Component2 } />
        <Route exact path='/route3' component={ Component3 } />
      </ContextB>
      <Redirect from='/' to='/route1' />
   </Switch>
</ContextA>

在那里, /route2/route3 共享一个上下文,期望应该是:

  1. 状态保持在路由转换之间。
  2. 如果 Component2Component3 更新上下文,则更改应反映给另一个。

对于公认的解决方案,以上都不是真的。

原文由 Nicolás Fantone 发布,翻译遵循 CC BY-SA 4.0 许可协议

看起来 <Switch> 应该只有 <Route><Redirect > 组件作为直接子组件。 ( 来源

我想这就是为什么你的 Redirect 在你使用 ContextB 作为 Switch 孩子时不起作用。

最简单但重复的解决方案可能是将您的 ContextB 作为每个 <Route> 你想要:

注意:这些解决方案假设您像这样分配了 Context 组件的默认值: const MyContext = React.createContext(defaultValue);

 <Route exact path='/route2'>
  <ContextB.Provider>
    <Component1 />
  </ContextB.Provider>
</Route>

您甚至可以为此创建一个 ContextRoute 组件:

 import React from 'react';
import { Route } from 'react-router-dom';

const ContextRoute = ({ contextComponent, component, ...rest }) => {
  const { Provider } = contextComponent;
  const Component = component;

  return (
    <Route {...rest}>
      <Provider>
        <Component />
      </Provider>
    </Route>
  );
};

export default ContextRoute;

然后将其用作路线:

 <ContextA>
  <Switch>
    <Route exact path='/route1' component={ Component1 } />
    <ContextRoute exact path='/route2' contextComponent={ContextB} component={ Component2 } />
    <ContextRoute exact path='/route3' contextComponent={ContextB} component={ Component3 } />
    <Redirect from='/' to='/route1' />
  </Switch>
</ContextA>

使用此解决方案,然后您可以在嵌套组件中使用带有渲染道具的上下文:

 return (
  <ContextB.Consumer>
    {value => <div>{value}</div>}
  </ContextB.Consumer>
);

但是我们可以想象更多的解决方案,比如 HOC ,将上下文值直接传递给路由组件 props,等等……

原文由 Nenu 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进