Похоже, что <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 , передавая значение контекста непосредственно в подпорки компонента маршрута и т. Д. *