Using react
18.2 with react-router-dom
6.3 I have my routes in this style
<Routes>
<Route path="/" element = {<App/>}>
<Route path="search" element = {<Content/>} />
<Route path="nextComp/:id" element = {<Component/>} />
</Route>
</Routes>
In my app, I have a dynamic nav bar that I want to stick around which could be used to select different generated components (generated by actions in the Content
component in /search
) There are states in my App
component that need to be set by the Content
component. I pass information down with something along the lines of:
const App: React.FC = () => {
const [lock, setLock] = useState<Boolean>(false);
const [lotsQuery, setLotsQuery] = useState<lotWaferQueryInput[]>([]);
const navigate = useNavigate();
const onClickHandle(() => {
navigate('/search', {state: {
setLock : setLock,
setLotsQuery: setLotsQuery
}});
}, []);
}
In my Content
component, I try accessing the data with :
const {state} : any = useLocation();
const {setLock,setLotsQuery} : any = state;
This results in Uncaught TypeError: Cannot destructure property 'setLock' of 'state' as it is null.
I understand that you can't directly serialize a function. How should I reapproach the way I'm routing data?
As of now, the hierarchy looks like
App
-Nav (child component)
-Content(search subroute)
-Component(nextComp subroute)
Data is entered in Content
, and then sent to App (which is the current problem of being able to set function). Data is handled by App
and then passed to nav and generates Component
(subroutes)
How can I achieve sending data from a subroute component to a parent route then? Any advice appreciated.
The route state needs to be JSON serializable, so sending functions just won't work. I suggest exposing the functions down to nested routes via the Outlet
's context and the useOutletContext
hook.
Example:
import { Outlet } from 'react-router-dom';
const App: React.FC = () => {
const [lock, setLock] = useState<Boolean>(false);
const [lotsQuery, setLotsQuery] = useState<lotWaferQueryInput[]>([]);
...
return (
...
<Outlet context={{ setLock, setLotsQuery }} />
...
);
};
In nested route's component:
import { useOutletContext } from 'react-router-dom';
...
const { setLock, setLotsQuery } = useOutletContext();
...
<Routes>
<Route path="/" element={<App />}> // <-- provides context value
<Route path="search" element={<Content />} /> // <-- can access context value
<Route path="nextComp/:id" element={<Component />} />
</Route>
</Routes>
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments