是否可以根据react-router-dom中同一url内的url参数值渲染不同的组件?

non*_*ame 5 reactjs react-router-dom

所以基本上标题是我的问题。是否可以仅通过更改 url 参数来实现类似的效果:

<路由路径={'/users/:id'} 组件={()=> UsersPage}/>

<路由路径={'/users/:filterOption'}组件={()=> UsersList}/>

Dre*_*ese 3

react-router-dom@5

是的,绝对可以。该Router组件包含匹配并渲染路由(与专门Switch匹配它们的组件相反)。这意味着将渲染与 prop 匹配的所有路由和重定向。Routerpath

给定路径“/users/someValue”:

<Router>
  <Route path={'/users/:id'} component={()=> UsersPage}/>
  <Route path={'/users/:filterOption'} component={()=> UsersList}/>
</Router>
Run Code Online (Sandbox Code Playgroud)

两个组件都可以匹配和渲染。

注意Route component道具!

路由渲染方法

当您使用component(而不是renderchildren)时,路由器将使用React.createElement给定组件创建新的 React 元素。这意味着如果您为组件属性提供内联函数,则每次渲染都会创建一个新组件。这会导致卸载现有组件并安装新组件,而不仅仅是更新现有组件。使用内联函数进行内联渲染时,请使用 render 或 Children 属性。

component这意味着如果您提供函数,则不应使用该道具。而是执行以下操作之一

<Router>
  <Route path={'/users/:id'} component={UsersPage}/>
  <Route path={'/users/:filterOption'} component={UsersList}/>
</Router>
Run Code Online (Sandbox Code Playgroud)

或者

<Router>
  <Route path={'/users/:id'} render={()=> <UsersPage />}/>
  <Route path={'/users/:filterOption'} render={()=> <UsersList />}/>
</Router>
Run Code Online (Sandbox Code Playgroud)

或者

<Router>
  <Route path={'/users/:id'}>
    <UsersPage />
  </Route>
  <Route path={'/users/:filterOption'}>
    <UsersList />
  </Route>
</Router>
Run Code Online (Sandbox Code Playgroud)

react-router-dom@6

react-router-dom@6现在总是完全匹配并使用路径排名/评分系统,并且 '/users/:id'具有'/users/:filterOption'相同的特异性并且将具有相同的分数。他们之间没有什么可以消除歧义的。相反,您将渲染单个路由,并需要使用useParams钩子来读取路由参数,无论是在包装器组件中还是直接在路由组件中。

包装组件的示例。

const UserWrapper = () => {
  const { id } = useParams();
  return (
    <>
      <UsersPage id={id} />
      <UsersList filterOption={id} />
    </>
  );
};
Run Code Online (Sandbox Code Playgroud)

...

<Router>
  <Routes>
    <Route path={'/users/:id'} element={<UserWrapper />} />
    ...
  </Routes>
</Router>
Run Code Online (Sandbox Code Playgroud)

  • 抱歉,如果我不明白什么,但在这个例子中,两个组件将同时渲染,不是吗?我如何“告诉”路由器我只想根据我的 ulr 参数渲染一个组件?现在,路由器“看到”“/users/”后面的一些参数并呈现这两个组件。我应该在我的组件中执行类似的操作(在本例中 UsersPage,它需要 id 作为 url 参数): if (!params.id) return &lt;div&gt;&lt;/div&gt; (2认同)