简体   繁体   中英

How to pass props to route components when using useRoutes?

I'm trying out the new useRoutes hook from react-router-dom and it seems to be pretty interesting. The only problem, is that I can't figure out how I would pass props down to the components.

Before, I'd have a Route component, and I would select parts of local or global state there and pass it on, but how would I do it with useRoutes ?

In the below sandbox, I'm trying to change the background based on the boolean value of isLoading . How would I pass isLoading on?

mystifying-paper-1khwd

Edit

Here's the code:

import React from "react";
import { BrowserRouter as Router, Outlet, useRoutes } from "react-router-dom";

const Main = ({ isLoading }) => (
  <div
    style={{
      height: "40vh",
      width: "50vw",
      backgroundColor: isLoading ? "red" : "pink"
    }}
  >
    <Outlet />
  </div>
);

const routes = [
  {
    path: "/",
    element: <Main />
  }
];

const App = ({ isLoading }) => {
  const routing = useRoutes(routes);
  return (
    <>
      {routing}
      {JSON.stringify(isLoading)}
    </>
  );
};

export default function Entry() {
  const [isLoading, setIsLoading] = React.useState(false);

  React.useEffect(() => {
    setInterval(() => {
      setIsLoading(!isLoading);
    }, 3000);
  }, [isLoading]);
  return (
    <Router>
      <App isLoading={isLoading} />
    </Router>
  );
}

Edit

I've considered passing in an isLoading argument to routes , but I feel like that won't be an efficient approach, because the whole tree will rerender at any route, regardless of whether or not it depends on isLoading or doesn't. Would a better approach be to use Switch and a custom Route component for routes that depend on isLoading and just use useSelector in that custom Route component?

I think this would work:

    const routes = (props) => [
      {
        path: "/",
        element: <Main {...props} />
      }
    ];
    
    const App = ({ isLoading }) => {
      const routing = useRoutes(routes({isLoading}));
      return (
        <>
          {routing}
          {JSON.stringify(isLoading)}
        </>
      );
    };

Instead of passing the array, you can create a function that returns a constructed array to the useRoutes hook:

const routes = (isLoading) => [
  {
    path: "/",
    element: <Main isLoading={isLoading} />
  }
];

code sandbox: https://codesandbox.io/s/dark-dream-hx1y9

more pretty would be:

const routes = (props) => [
  {
    "/": () => <Main {...props} />
  }
];
    
    
    const App = ({ isLoading }) => {
      const routing = useRoutes(routes(isLoading));

      return (
           <>
               {routing}
               {JSON.stringify(isLoading)}
           </>
      )
    };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM