I'm trying here on my application to do some tests with the new context API from React 16.3 but I can't understand why my redirect never works.
<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>
I don't want to have my ContextB available for all the routes, just 2 and 3. How can I do this?
Redux is much more powerful and provides a set of handy features that Context doesn't have. It's great for managing centralized state and handling API requests.
The useContext is the React hook, used in context API to consume the context state or object. There are two options for getting the context object. We can get the context object from Context Consumer or useContext Hook. UseContext Hook is an exquisite, more excellent way to get the context object with less code.
context is being shown as deprecated even though the official docs tells you to use it like this: class MyClass extends React. Component { componentDidMount() { let value = this. context; /* perform a side-effect at mount using the value of MyContext */ } componentDidUpdate() { let value = this.
This can be achieved using Redux. With the release of React version 16.3, the new Context API was introduced as a solution to React prop drilling. As stated in React Documentation: Context provides a way to pass data through the component tree without having to pass props down manually at every level.
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With