如果两个路径使用相同的元素,React 路由器不会重新加载组件

问题描述 投票:0回答:5

我设置了以下两条路径

<Route path="bookings/:bookingnumber" element={<Bookings />} />
<Route path="bookings" element={<Bookings />} />

Bookings
组件中,我编写了条件代码来检查参数
:bookingnumber
是否被传递,然后它只显示与该预订号码相关的结果。 否则,如果不传递参数,则显示所有预订的所有结果。

我使用

Outlet
在主区域中显示这些组件,并且可以从侧边栏中选择这两个路径。

假设我有

10 results
,如果我去
/bookings
,并且
2 results
,如果我去
/bookings/123

但是,如果我先转到

/bookings/123
,然后再转到
/bookings
,它会继续仅显示
2 results
(组件不会重新加载,但我可以在浏览器中看到 URL 发生变化)

reactjs react-router react-router-dom
5个回答
9
投票

问题

<Route path="bookings" element={<Bookings />} />
<Route path="bookings/:bookingnumber" element={<Bookings />} />

对于在多个路由上渲染的相同组件,如果您从一个路由导航到同一路由组件的另一路由,则路由的组件将保持挂载状态。

示例:如果从

"/bookings"
导航到
"/bookings/123"
,或从
"/bookings/123"
导航到
"/bookings"
,或从
"/bookings/123"
导航到
"/bookings/456"
,则
Bookings
组件保持安装状态。如果您有任何依赖于
bookingnumber
路由路径参数的逻辑,则
Bookings
组件需要在
useEffect
钩子中处理此问题,并正确依赖于
bookingnumber
参数。

解决方案

使用

useEffect
钩子“监听”
bookingnumber
参数值的更改。

示例:

const Bookings = () => {
  const { bookingnumber } = useParams();

  useEffect(() => {
    // initial render or booking number value updated
    // run logic depending on bookingnumber value to update "results"
    ... 
  }, [bookingnumber]);

  ...
};

7
投票

我也一直在努力解决这个问题,解决方案是添加

key
属性,反应用它来理解两个组件何时不同(否则它假设它们是相同的,并且它们不会被重新定义)渲染)。

因此您的案例的解决方案可能如下所示:

<Route key={'single'} path="bookings/:bookingnumber" element={<Bookings />} />

<Route key={'all'} path="bookings" element={<Bookings />} />


1
投票
<Route path="bookings" element={<BookingList />}>
  <Route path=":bookingnumber" element={<ViewBooking />} />
</Route>

制作两页,第一页将显示所有预订列表,第二页将显示 ID 数据


1
投票

您好,我相信您正在使用

react-router-dom v6
,在这种情况下,您可以将子路由包装在主路径路由中。然后给它们
index(true|false)
属性,以确保路由器了解它是否是确切的索引页面或应该根据参数渲染页面。

注意:我复制了上面的示例,并添加了一些行来修复它!

<Route path="bookings">
  <Route index={false} path=":bookingnumber" element={<ViewBooking />} />
  <Route index={true} element={<BookingList />} />
</Route>

更新: 您可以使用

useParams
钩子处理单个组件路由。

您的路由文件应如下所示:

<Route path="bookings">
  <Route index={false} path=":bookingnumber" element={<ViewBooking />} />
  <Route index={true} element={<BookingList />} />
</Route>

你的组件应该是这样的:

const MyComponent = () => {

  const { bookingnumber } = useParams()
  
  // if the path doesn't include the booking number then we should just render a normal page
  if( !bookingnumber ) {
    return <h1>This is a simple page</h1>
  }
  
  
  // if the page path does include the booking number then we can fetch data and return another result
  // example you can fetch data based on this number
  const [username, setUsername] = useState("")
  useEffect(() => {
    const fetchData = async () => {
      const req = await fetch(`https://629c770de9358232f75b55dc.mockapi.io/api/v1/users/${bookingnumber}`)
      const data = await req.json()
      setUsername(data.name)
    }
    fetchData()
  }, [username])

  return (
    <h1>Welcome mr.{username}</h1>
  )
}


0
投票

我也有同样的问题。常识在哪里?两种不同的路径为什么会自动重用组件。如果我想重用,我会使用相同的路径但具有不同的参数。

© www.soinside.com 2019 - 2024. All rights reserved.