React - 导航到同一个组件的奇怪行为

Posted

技术标签:

【中文标题】React - 导航到同一个组件的奇怪行为【英文标题】:React - Navigating to the same component weird behaviour 【发布时间】:2021-08-03 17:49:51 【问题描述】:

我对此感到头疼,我看到的行为对我来说似乎很奇怪,尽管对你们中的一些人来说可能是有道理的。

考虑这个组件:

const DishPreparation = ( dish ) => 
  const [slideIndex, setSlideIndex] = useState(0)
  const sceneRef = useRef(null)
  useKeepAwake();

  return (
    <View style=styles.scene ref=sceneRef>
      <View flex=0.12 style= marginTop:-10 >
        <ProgressSteps activeStep=slideIndex activeStepIconBorderColor=colors.lightTan completedProgressBarColor=colors.lightTan completedStepIconColor=colors.lightTan>
          dish.preparationSteps.map((step, index) => (
            <ProgressStep removeBtnRow key=index/> ))
        </ProgressSteps>
        ......
  )

这是通过另一个组件Dish 呈现的,可以导航到。我的应用程序中有一些浮动组件,允许我使用特定的菜导航到Dish。如果我第一次通过它导航到一道菜,或者如果我通过将组件推送到堆栈来通过其他组件导航到那里,一切正常。奇怪的行为是,当我已经在这个带有特定盘子的组件中,然后通过浮动组件导航到另一个盘子时,就像保留了旧盘子一样。

假设第一道菜在 dish.preparationSteps 中有 3 个元素,第二道菜有 4 个,那么 dish.preparationSteps.map(step, index) 只返回 3 个元素而不是 4,但是如果我在映射中渲染 step.someInfo,那么我实际上看到了新的菜肴价值。

这是怎么回事?我希望返回 4 个元素,或者返回 3 个元素但使用旧菜值,这种混合是如何发生的?另外,不知道它是否有帮助,但 slideIndex 保持其旧值,并且不会重新初始化为 0。

这就是我浏览浮动组件的方式:

navigation.navigate('Tabs', 
                        screen: 'Home',
                        params:  screen: 'Dish', params:  from: '', data: dish  ,
                      )

这就是我通过其他一些其他组件导航到它的方式(按预期工作)

navigation.push('Dish', from: 'DishList', data: item)

如果需要任何其他代码,我很乐意添加。

【问题讨论】:

您能否通过 github 或 expo snap 提供一个具有最少代码的工作示例? 【参考方案1】:

也许 getId 道具就是您要找的东西?

来自 React Navigation 文档:

在堆栈导航器中,使用屏幕名称调用导航将根据屏幕是否已经存在而产生不同的行为。如果该屏幕已经存在于堆栈的历史记录中,它将返回该屏幕并在此之后删除所有屏幕。如果屏幕不存在,它将推送一个新屏幕。

您可以改用 getId 属性来推送新屏幕。例如,假设您为 Profile 屏幕指定了一个 getId 属性:

<Screen name=Profile component=ProfileScreen getId=( params ) => params.userId />

现在,如果您有一个带有历史记录 Home &gt; Profile (userId: bob) &gt; Settings 的堆栈,并且您调用 navigate(Profile, userId: 'alice' ),则生成的屏幕将为 Home &gt; Profile (userId: bob) &gt; Settings &gt; Profile (userId: alice) ,因为它会添加一个新的 Profile 屏幕,因为找不到匹配的屏幕。

【讨论】:

【参考方案2】:

当使用 .navigate 而不是 .push 时,导航将查找该屏幕名称(“Dish”)并仅更改导航参数,而无需重新安装组件或使用它打开新屏幕。通常您可以只使用 navigation.push (就像在上一个示例中一样),但问题是您正试图从某个***导航器导航。您不能在那里使用 .push ,因为它会推送到没有“Dish”屏幕的外部导航器。如果要在嵌套导航器中的现有屏幕之上添加另一个“Dish”屏幕,则需要从要导航的 Stack Navigator 中使用 navigation.push ;只是你的浮动不在那个 Stack Navigator 中

您可以尝试的第一件事是在导航时将唯一的key 添加到您的屏幕,例如

navigation.navigate('Tabs', 
  screen: 'Home',
  params:  screen: 'Dish', key: dish.id, params:  from: '', data: dish  ,
)

这样导航将不按名称而是按名称和键来比较屏幕。这很可能会用新的 Dish 屏幕替换现有的 Dish 屏幕

更好的解决方案是发送navigation action,它将深入到您要导航的堆栈导航器,然后在那里发送StackActions.push

更好的解决方案是不要尝试从外部导航器中导航到内部导航器

【讨论】:

不幸的是,第一个解决方案不起作用,如果我从一个有更多preperationSteps的菜导航到一个更少的菜,它会抛出一个未定义的错误(试图到达props.children[i] for i that不存在。与没有唯一键的行为相同.. 在您的第二个解决方案中,您的意思是这样的吗? navigation.navigate('Tabs', screen:'Home'); navigation.push('Dish', from: '', data: dish); ?因为这对我有用,只是不确定它是否是好的做法 1.尝试找出问题所在(您为什么要尝试访问 props.children?屏幕组件中没有子项) 2. 不,您的建议只是调用 .navigate 然后调用 .push。在我链接的页面上有调度导航操作的示例 1.我不是..它的组件ProgressSteps 试图到达映射返回的每个ProgressStep,它是来自github 的组件,但这意味着它仍然使用旧状态.. 2. 我只是想做好的,我会调查的

以上是关于React - 导航到同一个组件的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

具有奇怪行为的 UINavigationController

React 中的 SVG 平移会导致奇怪的行为

导航到下一页时,Chrome (iOS) 中的奇怪自动滚动/跳转行为

反应钩子useState()的真正奇怪的行为

从嵌入式导航控制器推送 viewController 时的奇怪行为

拆分视图控制器导航栏的奇怪行为