It looks like that <Switch>
should only have <Route>
and <Redirect >
components as direct children. (source)
I suppose that's why your Redirect
doesn't work as you use ContextB
as a Switch
child.
The simplest but repetitive solution could be to pass your ContextB
as a child of each <Route>
you want:
Note: These solutions suppose that you assigned the default value of your Context component like this: const MyContext = React.createContext(defaultValue);
<Route exact path='/route2'>
<ContextB.Provider>
<Component1 />
</ContextB.Provider>
</Route>
You can even create a ContextRoute
component for this:
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;
And then use it as a 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>
With this solution, you then use your context with render props in your nested Components:
return (
<ContextB.Consumer>
{value => <div>{value}</div>}
</ContextB.Consumer>
);
But we can imagine much more solutions to this like HOC, passing context value directly to the route component props, etc...
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…