如何为 React Router 6.4+ 路由提供动态自定义 Props

han*_*rig 5 javascript reactjs react-router react-router-dom

我正在尝试使用最新的 React Router 6.4 为 React Router Route 定义提供动态自定义道具。我找不到任何例子来展示我如何实现这一目标。这些是由RouterProvider声明的父组件提供的 props。

6.0 - 6.3官方文档的示例:

// Ah, nice and simple API. And it's just like the <Suspense> API!
// Nothing more to learn here.
<Route path=":userId" element={<Profile />} />

// But wait, how do I pass custom props to the <Profile>
// element? Oh ya, it's just an element. Easy.
<Route path=":userId" element={<Profile animate={true} />} />
Run Code Online (Sandbox Code Playgroud)

在 6.4 中,您的路由定义类似于:

// How do I provide animate state from App component to Policy component?
const router = createBrowserRouter([{ path: '/', element: <Profile animate={animate} /> }];

export function App() {
    const [animate, setAnimate] = useState(true);
    return <RouterProvider router={router} />
}
Run Code Online (Sandbox Code Playgroud)

Dre*_*ese 11

在您提供的示例中,您已经将一个animateprop 传递给了路由组件。RRDv6.4.0 没有更改Route组件 API。看来您的问题实际上是关于在访问路线时传递动态道具值。

router声明移至组件中App,以便animate状态位于范围内。

例子:

function App() {
  const [animate, setAnimate] = useState(true);

  const router = createBrowserRouter([
    { path: "/", element: <Profile animate={animate} /> } // <-- pass prop value
  ]);

  return (
    <div className="App">
      ...
      <RouterProvider router={router} />
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

编辑 how-to-provide-custom-props-to-react-router-6-4-route

为了避免router每次父组件重新渲染时都重新创建,您可以使用钩子来记忆它useMemo

function App() {
  const [animate, setAnimate] = useState(true);

  const router = createBrowserRouter([
    { path: "/", element: <Profile animate={animate} /> } // <-- pass prop value
  ]);

  return (
    <div className="App">
      ...
      <RouterProvider router={router} />
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是将状态移动到布局路由中,并通过布局路由的Outlet上下文提供程序向下传递状态。消费者使用useOutletContext钩子来访问提供的值。这意味着router可以将声明移出 React 组件并作为稳定的引用提供。

例子:

const Profile = () => {
  const { animate } = useOutletContext();

  ...

  return (
    ...
  );
};
Run Code Online (Sandbox Code Playgroud)
const AppLayout = () => {
  const [animate, setAnimate] = useState(true);

  return (
    <>
      ...
      <Outlet context={{ animate, /* other values */ }} />
      ...
    </>
  );
};

const router = createBrowserRouter([
  {
    element: <AppLayout />,
    children: [{ path: "/", element: <Profile /> }]
  }
]);

export default function App() {
  return (
    <div className="App">
      <RouterProvider router={router} />
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)

编辑 how-to-provide-custom-props-to-react-router-6-4-route (分叉)

  • 感谢您展示这一点,我是否应该担心每当重新渲染应用程序组件时都会重新创建路由器? (2认同)