Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing set statehook function into subroute component. Destructuring error

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.

like image 334
twSoulz Avatar asked Jun 28 '26 11:06

twSoulz


1 Answers

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>
like image 139
Drew Reese Avatar answered Jul 01 '26 23:07

Drew Reese



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!