I am wondering how to share state between my two routes. Should I lift state up from my AddContact
component to Layout
or App
to share to ContactList
. My Layout
component is just rendering a Header
and Outlet
component.
function App() {
const [contacts, setContacts] = useState([])
return (
<BrowserRouter>
<Routes>
<Route element={<Layout />}>
<Route path='/' element={<ContactList />} />
<Route path='/add' element={<AddContact />} />
</Route>
</Routes>
</BrowserRouter>
);
}
You could lift it to either.
If lifting state to App
you can pass what you need down as props to each routed component.
Example:
function App() {
const [contacts, setContacts] = useState([]);
return (
<BrowserRouter>
<Routes>
<Route element={<Layout />}>
<Route
path="/"
element={<ContactList contacts={contacts} />}
/>
<Route
path="/add"
element={<AddContact setContacts={setContacts} />}
/>
</Route>
</Routes>
</BrowserRouter>
);
}
The alternative is to locate the state in the Layout
layout route component and expose via the Outlet
component's context. The routed components would access the provided context value via the useOutletContext
hook.
function App() {
return (
<BrowserRouter>
<Routes>
<Route element={<Layout />}>
<Route path="/" element={<ContactList />} />
<Route path="/add" element={<AddContact />} />
</Route>
</Routes>
</BrowserRouter>
);
}
const Layout = () => {
const [contacts, setContacts] = useState([]);
return (
...
<Outlet context={{ contacts, setContacts }} />
...
);
};
const ContactList = () => {
const { contacts } = useOutletContext();
...
};
const AddContact = () => {
const { setContacts } = useOutletContext();
...
};
It basically comes down to preference, or scope in my opinion, e.g. how much of the sub-ReactTree needs to access the state.