Looking through old tutorials it seems like React Router v5 had support for sharing state across different routes using the context API but I can't find anything on a similar usage for Router v6.
React Router v5 Implementation of what I am trying to do:
const [user, setUser] = useState(null);
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about/">About</Link>
</li>
</ul>
</nav>
<UserContext.Provider value={user,setUser}>
<Route path="/" exact component={Index} />
<Route path="/about/" component={About} />
</UserContext.Provider>
</div>
</Router>
);
and then you can access the state using the useContext
hook
const {value, setValue} = useContext(UserContext);
v6 Implementation
When attempting to use this implementation with v6 (exchanging the degraded v5 components for the new v6 ones) you will run into errors because you can only have <Route>
components as children in a router.
Is it possible to share state with a global context store across React Router V6 routes?
Below is my attempt at V6 implementation:
index.js
import { BrowserRouter as Router } from "react-router-dom";
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById("root")
);
App.js
const [value, setValue] = useState("initial state");
return (
<>
<Header props={(key, setKey)} />
<DataContext.Provider value={(value, setValue)}>
<Route path="/" element={<Dashboard />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/configuration" element={<Configuration />} />
</DataContext.Provider>
</>
);
App.js different Approach
const [value, setValue] = useState("initial state");
return (
<DataContext.Provider value={(value, setValue)}>
<Header props={(key, setKey)} />
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/configuration" element={<Configuration />} />
</Routes>
</DataContext.Provider>
);
}
The issue with this solution is the state is still not updated globally when changed in one of the routes.
For example in /dashboard
if I change value using setValue
then it will reflect the changes in /dashboard
but if I navigate to /configuration
or refresh value
will have reverted to original value
, "initial state" in this case. (This is also the effect if I make a function in App.js
which will use setValue
and I pass the function to Provider instead)
I am sure that I could use React Redux to solve this problem but its really just one or two pieces of data that I need shared between routes - seems like overkill to implement all of the required redux boilerplate etc. and seems like a common use case that context should support.
App.js
approach appears correct, i.e. you've wrapped the components that consume the context value and you've correctly wrapped theRoute
components in theRoutes
component. What isn't working as expected? – Mairamaire