看起来<Switch> 应该只有<Route> 和<Redirect > 组件作为直接子级。 (source)
我想这就是为什么你的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;
然后将其用作Route:
<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,将上下文值直接传递给路由组件道具等...