为react-router-dom v6 Route创建包装组件来记录路由更改

Can*_*ice 1 reactjs react-router-dom react-component

我们希望向我们的 React 应用程序添加自定义日志记录,并希望在每次用户更改路由时进行记录。为了解决这个问题,我们正在创建一个包装组件,这就是我们目前拥有的:

\n
import React, { useEffect } from 'react';\nimport { Route } from 'react-router-dom';\n\nfunction LoggerRoute(isExact, path, element) {\n    useEffect(() => {\n        // send route-change log event to our mongodb collection\n    }, []);\n\n    // And return Route\n    return (\n        isExact\n            ? <Route exact path={path} element={element} />\n            : <Route exact path={path} element={element} />\n    );\n}\n\nexport default LoggerRoute;\n
Run Code Online (Sandbox Code Playgroud)\n

...在我们的 App.js 文件中,我们更改了路由:

\n
// remove this // <Route exact path='/tools/team-scatter' element={<TeamScatterApp />} />\n<LoggerRoute isExact={true} path='/tools/team-scatter' element={<TeamScatterApp />} />\n
Run Code Online (Sandbox Code Playgroud)\n

但是,这会引发错误Uncaught Error: [LoggerRoute] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>

\n

此外,将道具传递给路线感觉不太好,如果可能的话我们更喜欢

\n
<LoggerRoute exact path='/tools/team-scatter' element={<TeamScatterApp />} />\n
Run Code Online (Sandbox Code Playgroud)\n

作为调用 LoggerRoute 的理想方式。我们喜欢包装器组件的想法,这样我们就不必将日志记录添加到我们的应用程序路由到的每个组件中。但是,I\xe2\x80\x99m 不确定如果只能接受组件,这种包装组件方法是否可行。我们该如何修改我们的LoggerRoute组件才能工作/变得更好?

\n

Dre*_*ese 5

react-router-dom@6Route是组件React.Fragment的有效子组件Routes。创建包装器组件或布局路由组件来处理监听路由路径更改。由于您可能希望一次对多个路由执行此操作,因此我建议使用布局路由方法,但您可以创建一个处理任一路由的组件。

例子:

import { Outlet, useLocation } from 'react-router-dom';

const RouteListenerLayout = ({ children }) => {
  const { pathname } = useLocation();

  useEffect(() => {
    // send route-change log event to our mongodb collection
  }, [pathname]);

  return children ?? <Outlet />;
};
Run Code Online (Sandbox Code Playgroud)

propchildren用于包装单个路由组件(elementpropApp渲染一组Routes. 该Outlet组件用于您想要有条件地在组件中包含路由子集Routes即一些嵌套Route组件)的情况。

将您想要监听路线变化的路线包裹起来。

例子:

<Routes>
  <Route element={<RouteListenerLayout />}>
    <Route path="path1" element={<SomeComponent />} />
    <Route path="someOtherPath" element={<SomeOtherComponent />} />
    ... wrapped routes components with listener
  </Route>
  ... routes w/o listener
</Routes>
Run Code Online (Sandbox Code Playgroud)

或者

<Routes>
  <Route
    path="/"
    element={(
      <RouteListenerLayout>
        <SomeComponent />
      </RouteListenerLayout>
    )}
  />
</Routes>
Run Code Online (Sandbox Code Playgroud)

或者

<RouteListenerLayout>
  <App />
</RouteListenerLayout>
Run Code Online (Sandbox Code Playgroud)

这些都假设路由器在 ReactTree 中呈现得比预期更高,RouteListenerLayout因此useLocation挂钩可以按预期工作。