从一个切换到另一个时,React child 组件只更新了一半

React child components are only half updating when switching from one to the other

我有一个包含 2 个硬编码路由和 2 个映射路由的主组件,我正在将计划 object 解析为计划组件。

<Routes>         
    <Route path='/' element={<Heading>index</Heading>}/>
    <Route path='/profile' element={<Profile />}/>
    {user && 
        user.workoutPlans.map((plan, index) => (    
            plan._id && <Route path={'/' + plan._id} key={index} element={<Plan plan={plan} />} /> 
    ))} 
</Routes> 

计划组件显示计划标题并包含一个部分,它将天数数组映射到 DayCards

<Heading size='2xl' mr={-3}>{plan.title}</Heading>
<Flex direction='column'>
    {plan.days.map((day, index) => (
        day._id && <DayCard planId={plan._id} day={day} key={index} />
    ))}
</Flex>

如果我刷新然后转到路线应用程序。com/plan1id 我得到了正确的日期列表 [day1, day2, day3, day4, day5] + Heading: Plan1

如果我刷新然后转到路线应用程序。com/plan2id 我得到了正确的日期列表 [other1, other2, other3] + 标题:Plan2

但是如果我从 app.com/plan2id 转到 app.com/plan1id 我得到了一个混乱的日期列表 [other1, other2, other3, day4, day5] + 标题:Plan1

倒序一样

但是如果我刷新然后转到路由应用程序。com/plan1id然后转到应用程序。com/profile 然后到 app.com/plan2id 它可以正常返回 [other1, other2, other3] + Heading: Plan2

应用程序状态始终保持不变,据我所知,计划数据被正确解析,因为 plan.title 始终正确显示

任何关于为什么会这样的想法都将不胜感激

不要将数组索引用作 React 键。

当切换计划时,路线发生变化,但 Plan 组件保持安装状态,只有 plan 属性值更新。这会触发重新渲染。 但是 因为现在使用数组索引作为 React 键,键不会改变值。计划“A”中的日期索引 2 等于计划“B”中的日期索引 2。

您应该改用被映射数据固有的值。 GUID 是很棒的 React 键。我建议使用 day._id 作为 React 键,假设它们是唯一的。

<Flex direction='column'>
  {plan.days
    .filter(day => day._id)
    .map((day) => <DayCard planId={plan._id} day={day} key={day._id} />)
  }
</Flex>

也可以更正 Plan 组件的路由代码。

<Routes>         
  <Route path='/' element={<Heading>index</Heading>} />
  <Route path='/profile' element={<Profile />} />
  {user?.workoutPlans
    .filter(plan => plan._id)
    .map((plan) => (
      <Route
        path={`/${plan._id}`}
        key={plan._id}
        element={<Plan plan={plan} />}
      />
    ))
  }
</Routes> 

你还应该在路线 <Heading> 中使用精确的道具,否则当你导航到 /profile 或其他路线时,航向将首先得到调用。

如需更多参考,请查看此 link

<Routes>         
  <Route exact path='/' element={<Heading>index</Heading>} />
  <Route path='/profile' element={<Profile />} />
  {user?.workoutPlans
    .filter(plan => plan._id)
    .map((plan) => (
      <Route
        path={`/${plan._id}`}
        key={plan._id}
        element={<Plan plan={plan} />}
      />
    ))
  }
</Routes>