什么可能导致 React Native 组件不断地卸载和重新安装?

Posted

技术标签:

【中文标题】什么可能导致 React Native 组件不断地卸载和重新安装?【英文标题】:What might be causing a React Native component to continuously un- and re-mount? 【发布时间】:2021-05-26 03:46:09 【问题描述】:

我有一个组件,它呈现一个子组件,当从另一个组件中调用它时,它会不断卸载并重新安装。我不明白这是为什么。

代码大致如下:

import React,  useState  from 'react';
import  View  from 'react-native';
import EditLayout from './EditLayout'

export default users = (props) => 
    let  user  = props
    const [layout, setLayout] = useState([])
    const [layout, setLayout] = useState([])
    const Header = () => 
      return (<View>
                    <EditLayout layout=layout user=user  />
              </View>
      )
    
    
    return (
      <View style= flex: 1 >
            /* <EditLayout layout=layout user=user  /> */
            <Header />
      </View>
    );
  

这会导致 EditLayout 的许多重新渲染(EditLayout 非常少)。

当我将上面注释掉的代码替换为 /* / 改为 / */ 时,重新安装就会消失。似乎由于某种原因在 Header 内部调用时,它会导致许多 un & remounts 最终稳定下来。

知道是什么原因造成的吗?

编辑:编辑布局和输出

这是相关的 EditLayout 代码,即使只有下面这个,我也可以复制问题(因此它似乎与 EditLayout 代码的其余部分无关)。

在这里,我将 checkStateData 设置为默认的“Mounted Edit Layout”并立即将其更改为 false,仅在为 true 时打印。

export default EditLayout = (props) => 
    const [checkStateData, setCheckStateData] = useState("Mounted Edit Layout")

    checkStateData && console.log("*****", checkStateData) // Print the current status 

    useEffect(() => 
      if(setCheckStateData)
        console.log("Made it here")
        setCheckStateData(false)
      
    , [])
    
    return (
      <View style= flex: 1 >
            /* headerLayoutData && headerLayoutData.map((card, i) => 
                          if (card && user)
                            return <Card card=card key=i user=user />
                          
                        )
          newCards && newCards.map((card, i) => 
              return <NewCard key=i user=user />
          ) */
    
      </View>
    );
  
Via <Header />

[Tue Feb 23 2021 15:43:11.836]  LOG      ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:11.853]  LOG      Made it here
[Tue Feb 23 2021 15:43:12.127]  LOG      ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.172]  LOG      Made it here
[Tue Feb 23 2021 15:43:12.179]  LOG      ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.259]  LOG      Made it here
[Tue Feb 23 2021 15:43:12.281]  LOG      ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.300]  LOG      Made it here
[Tue Feb 23 2021 15:43:12.303]  LOG      ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.307]  LOG      Made it here
[Tue Feb 23 2021 15:43:12.309]  LOG      ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.314]  LOG      Made it here
[Tue Feb 23 2021 15:43:12.364]  LOG      ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.373]  LOG      Made it here
[Tue Feb 23 2021 15:43:12.373]  LOG      ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:12.384]  LOG      Made it here


Without <Header>
[Tue Feb 23 2021 15:43:32.797]  LOG      ***** Mounted Edit Layout
[Tue Feb 23 2021 15:43:32.856]  LOG      Made it here

【问题讨论】:

这里没有错,除了重复的状态。也请分享您的 EditLayout 组件。 我刚刚更新了它,将其简化为仍然可以重现的地方。 你在一个组件中定义一个组件,这应该会导致很难看到错误。 是否只是创建另一个文件并调用该文件?有区别吗? 哇你们真好!!!谢谢!谢谢!再次感谢您! 【参考方案1】:

在您当前的代码中,每次重新呈现 Users 组件时都会重新创建 Header(一个组件)。这将导致错误,因为您不想重新创建子组件(相反,它可能会在需要时重新呈现)。

为了防止这种情况,您应该在父组件之外定义Header,即Users(名称应以大写开头)。

所以,Header 可以在不同的文件中,也可以在同一个文件中(但在Users 之外)。如果Header 是一个很大的组件,最好将它保存在不同的文件中。

// 不要这样做

function MainComp() 

  //...
  function ChildComp() 
    // ... 
  


// 改为这样做

function MainComp() 
  // ... 


function ChildComp() 
  // ... 

【讨论】:

以上是关于什么可能导致 React Native 组件不断地卸载和重新安装?的主要内容,如果未能解决你的问题,请参考以下文章

本地化 React 和 React-Native 组件,使其尽可能可重用

Flatlist React-Native 组件防止我的数组填充导致应用程序崩溃

哪种方式更好地将对象传递给 React Native 中的转储组件?

React Native 调用原生Android组件

如何在 react-native 中使用 Navigator 组件复制 NavigatorIOS 组件行为?

React Native 中组件之间的道具和共享数据