reactjsreact-routerreact-state-management

State management with react-router


I am having a basic react app like

App.js -

const [mode, setMode] = useState("Light");
const setMode = () => {
    /*
        ....
    */
}
const handleFire = () => {
    /*
        ....
    */
}

return(
    <>
        <Navbar mode={mode} handleFire={handleFire}/> //Common element
        <Home mode={mode}/> //For route 1
        <About mode={mode}/> //For route 2
    </>
);

Following the tutorial on react-router website, I wish to implement react-router with the following app architecture (which of course, breaks):-

App.js -

const router = createBrowserRouter([
    {
      path: "/",
      element: <Root/>,
      children: [
        {
          path: "/home",
          element: <Home mode={mode}/>
        },
        {
          path: "/about",
          element: <About mode={mode}/>
        }
      ]
    }    
]);
return (
    <RouterProvider router={router} />
);

Root.js -

return(
    <>
        <Navbar mode={mode} handleFire={handleFire}/>
        <Outlet>
    </>
);

The major issue I am facing is handling the state mode across these files. In the present scenario, if I declare and setup the state logic in App.js, then I will get error that the state if not defined for Root.js and vice-versa.

Perhaps I need to figure out a better approach to design the app and work upon the state management. How can I refactor my app to make it less complicated and make the routing work as intended?


Solution

  • You could handle the state for mode in App and pass it down through context.

    import { createContext, useState } from 'react';
    export const ModeContext = createContext();
    function App() {
      const [mode, setMode] = useState('light');
      return (
        <ModeContext.Provider value={{mode, setMode}}>
          <RouterProvider router={router} />
        </ModeContext.Provider>
      );
    }
    

    Then, any component can get (or set) the value.

    import { ModeContext } from './App';
    import { useContext } from 'react';
    function Home() {
        const { mode } = useContext(ModeContext);
        return 'Home content...';
    }