Search code examples
reactjsreact-routerreact-router-dom

Passing props to <Outlet /> when nesting routes in React Router v6?


How can I pass props to the <Outlet /> component when I am nesting routes?

// Parent Comp 
{
  const [format, setFormat] = useState('rgb');
  const color = [hex, rgb, rgba]
  
  // ...

  return (
    <PaletteNavBar changeFormat={setFormat}/>

      {colorId ? <ColorBoxes /> : <Outlet color={color[format]} />}

      // setFormat(hex) is called down here
    <PaletteFooter />;
  )
}

I don't want to pass them via URL parameters.


Solution

  • The Outlet doesn't take any props, nor will it pass anything as props on to what it renders. It is simply an output for children routes of a component.

    Pass them to the component rendered by the Route, it's the Route that is rendered into the Outlet.

    Example:

    const Layout = () => (
      <div className="super-style">
        <h1>My super awesome layout container</h1>
        <Outlet /> // <-- children routes rendered here
      </div>
    );
    

    ...

    <Routes>
      <Route element={<Layout />}>
        <Route // <-- rendered into Outlet of Layout
          path="..."
          element={<Component foo="bar" />} // <-- pass props to component here
        />
        ... other routes for outlet
      </Route>
    </Routes>
    

    However, the Outlet does provide a React context that can be accessed via the useOutletContext hook since it's a common enough pattern for parent routes to manage some state or value to be shared with children routes.

    const Layout = () => (
      const [foo, setFoo] = React.useState();
    
      <div className="super-style">
        <h1>My super awesome layout container</h1>
        <Outlet context={[foo, setFoo]} /> // <-- pass context value
      </div>
    );
    

    ...

    <Routes>
      <Route element={<Layout />}>
        <Route path="..." element={<Component />} />
        ... other routes for outlet
      </Route>
    </Routes>
    

    ...

    import { useOutletContext } from 'react-router-dom';
    
    const Component = () => {
      const [foo, setFoo] = useOutletContext(); // <-- access context value
    
      ...
    };