useOutletContext

A layout route often holds something its child routes need — a selected filter, an editing flag, a setter. <Outlet> already has the slot: pass a context prop, and whichever child is rendered reads it back with useOutletContext().

A layout route sharing state with whichever child is mountedJavaScript
function ReportLayout() {
  const [range, setRange] = useState('month');
  return <div>
    <select value={range} onChange={(e) => setRange(e.target.value)}>
      <option value="week">This week</option><option value="month">This month</option></select>
    <Outlet context={{ range, setRange }} /></div>;
}
const Revenue = () => <p>Revenue for: {useOutletContext().range}</p>;

ReportLayout mounts once and owns the state, so switching between child routes changes only what fills the outlet: the selected range survives the navigation, because the parent is a route, mounted as long as the URL stays inside it.

Unlike every other hook in this section, useOutletContext() does not require a data router; <Outlet context> works identically inside a declarative <BrowserRouter> tree. In TypeScript, have the layout export a typed hook — export const useRange = () => useOutletContext<RangeContext>(). Keep the value small: it is plain React 7,897 context (Context Performance Pitfalls).