Reputation: 82
I have a parent component which is having Outlet
for sub routes.
I wanted to pass the data from the parent component (App.js
) to the component rendered by Outlet
for the default Link (Test.js
).
For which, I used the state object of location and passed the data from parent Component.
<Link to="" state={{ data }}>
Render test
</Link>
Although on initial render, it is still null in child component (Test.js
), but if I navigate to some other route (route: /dummy
, component : Dummy.js
) within that parent and come back to Test.js
components route, I am able to see value in the location.state
.
Codesandbox link for more clarity: https://codesandbox.io/s/location-state-zjs5rt
I tried adding location.state
as dependency in useEffect
but it is not getting triggered on the initial render.
useEffect(() => {
if (location.state) {
setTestData(location.state.data);
}
}, [location?.state]);
I wanted to pass some async data from App.js
and use it inside Test.js
component to render certain things, how can I achieve this?
Upvotes: 1
Views: 481
Reputation: 203562
If you are just wanting to make available some state in the App
component to any of the nested route's element
components then I'd suggest passing it via the React context available via the Outlet
component. The routed components use the useOutletContext
hook to access the context.
Example:
App
import { Outlet, Link } from "react-router-dom";
import { useEffect, useState } from "react";
export default function App() {
const [data, setData] = useState(null);
useEffect(() => {
setTimeout(() => {
setData("data that comes later");
}, 2000);
}, []);
return (
<div className="App">
{data ? (
<>
<h2>This is APP component</h2>
<ul>
<li>
<Link to="/">Render test</Link>
</li>
<li>
<Link to="/dummy">Another dummy component</Link>
</li>
</ul>
<Outlet context={{ data }} /> // <-- passed in context
</>
) : (
<>Loading...</>
)}
</div>
);
}
Test
import { useEffect } from "react";
import { useOutletContext } from "react-router-dom";
export default function Test(props) {
const { data } = useOutletContext();
useEffect(() => {
console.log("data using location", data);
}, [data]);
return <div>This is another component "{data}"</div>;
}
Upvotes: 1