【问题标题】:React Router v6: Accessing global state in Loader functionsReact Router v6: Accessing global state in Loader functions
【发布时间】:2022-12-27 20:46:57
【问题描述】:

I am giving react-router v6 a try and I feel like I am missing an important concept when it comes to router loaders. For example, in the react-router tutorial where it talks about the loader for the /contacts/:contactId route, I get that you can easily access any state that is contained in the URL, like the contactId in this case. However, I find that in addition to the route parameters I also need things like a userId which normally I would have available through a prop or a context provider since I like to keep auth information more global. So I'm having a hard time seeing how to access global state like that inside of the loader function.

To get more specific, my index.js file is set up like this, where I initialize the router object and then pass it to the root.render() function:

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
    children: [
      {
        path: "/user-specific-resources",
        element: <UserResources />,
        loader: resourceLoader,
      },
  }
]);


const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

However, the resourceLoader function for the /user-specific-resources route needs to know the userId/token to pass to the server. I know I could pass the userId as a route parameter like /user-specific-resources/:userId, but that feels a little awkward because the userId is pretty long. I know I could create some sort of globally-accessible object that contains the user state and pass that to a factory function that returns the user-aware loader, e.g. loader: resourceLoaderFactory(userStateManager). But for some reason to me that seems to run contrary to the ethos of react-router v6. So I know there are ways to make this happen, but I love that react-router has such nice separation of concerns when it comes to route-specific logic and the solutions I have thought of feel a little awkward. So really my question is, does react-router v6 have a more elegant way of handling this sort of thing which I missed when reading the documentation, or is this just the messiness that always comes when you leave the toy problem that was used in the tutorial and start writing more "real world" code?

【问题讨论】:

  • What sort of "global state/context" are you needing to access? Depending on what you need to access, and how it can be accessed, changes the solution. Can you include a more complete minimal reproducible example for what you are trying to accomplish?

标签: reactjs react-router-dom


【解决方案1】:

This issues is discussed here: https://github.com/remix-run/react-router/issues/9324

Here is my temporary solution to this problem. You can wrap RouterProvider and routes creation with a custom one that uses hooks.

const CustomRouterProvider = () => {
 const {userId, setUserId}= useState(); // or get it from context/custom hook

 const router = createBrowserRouter([
   {
     path: "/",
     element: <UserResources/>,
     loader: async () => {
           resourceLoader(userId);
         },
   },
 ]);

 return (
   <RouterProvider router={router} />
 );
}

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
      <CustomRouterProvider />
  </React.StrictMode>
)

【讨论】:

    猜你喜欢
    • 2022-01-17
    • 2023-01-17
    • 2022-01-21
    • 2022-01-24
    • 1970-01-01
    • 2022-06-18
    • 2022-11-11
    • 2023-01-20
    • 2023-02-06
    相关资源
    最近更新 更多