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...