Javascript 在ReactJS中重新渲染子对象3次是否可以接受?

Javascript 在ReactJS中重新渲染子对象3次是否可以接受?,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,假设我有3个组件连接在一个父组件中 伪示例: <div> <Parent /> <ChildMetaData /> <ChildData /> </div> 状态改变 =>所有3个组件都重新渲染。 当myloadChildRequestsFromServer()完成时,它会更改全局变量的状态 =>所有3个组件都重新渲染。 当myloadUserDataFromServer()完成时,它会更改全局变量的状态 =>所有3个组件都重新

假设我有3个组件连接在一个父组件中

伪示例:

<div>
 <Parent />
 <ChildMetaData />
 <ChildData />
</div>
状态改变

=>所有3个组件都重新渲染。

当my
loadChildRequestsFromServer()完成时,它会更改全局变量的状态

=>所有3个组件都重新渲染。

当my
loadUserDataFromServer()完成时,它会更改全局变量的状态

=>所有3个组件都重新渲染。

如您所见,当我单击我的父对象时,我的组件将重新渲染3次。(我通过在组件的一个渲染函数中运行console.log来检查,如

这是可以接受的行为,还是我做错了什么


我应该注意到,“从服务器加载”这两个函数都是AJAX调用。由于
loadChildRequestsFromServer()
this.loadUserDataFromServer()
是链接在一起的,也许我不应该在第一个函数结束后立即更新状态。而是将数据传递给下一个函数,并在那里更新数据。

组件重新渲染3次是完全正确的。
因为您的父母有三种不同的状态:

  • 没有任何ajax结果
  • 使用第一次调用的ajax结果
  • 使用两个调用的ajax结果
  • React将过滤掉所有不必要的DOM更新,这是主要的性能瓶颈。 通过实现
    shouldComponentUpdate()
    ,可以过滤掉不必要的更新。这也将防止不必要地执行
    render()
    函数

    (更新)如果第一个子级只需要第一个ajax调用结果,而第二个子级只需要第二个调用结果,那么您也可以考虑给出每个子级状态,并从其各自的子级中调用每个函数。
    这样,每个子对象都会独立更新,并且得到的渲染调用更少。 与原始解决方案相比,DOM更新的数量将保持不变=最小


    如果您永远不需要只有一个ajax调用结果的状态,那么您可以像您描述的那样进行链接。但这会使任何错误处理变得更加棘手。

    您的伪示例中的组件没有父子关系,它们只是兄弟。它们在数据库中是子-父/主从,这就是为什么我给它们命名的原因。我想你可以忽略组件的命名。它会让人困惑。但是它对我来说有语义意义。你可以考虑添加一个可选参数来抑制重新渲染,因为当你知道你将依次执行多个触发调用。是获取数据并重新渲染的内容,不会渲染,因为我们仍然没有渲染所需的任何数据。React不会触动,因为这将是一个不必要的更新。然后loadUserDataFromServer()完成。不依赖于该数据,所以react不会触及它的DOM,但确实如此,所以它会呈现它。现在,如果我运行console.log,它将只记录对呈现函数的调用,但DOM实际上不会更改3次。我做对了吗?是的。另一个答案是:你可以考虑把每个调用放在各自的组件中。这样,家长不需要更新3次,每个孩子只更新2次(初始+ajax结果)。太棒了,明白了!你认为哪个更好?要让所有ajax功能都在某个父范围内,还是在每个单独的组件中?我仍然缺乏经验,所以很难找出哪种情况更好。起初,我认为最好将所有数据获取函数放在一个全局范围内,这样我就可以从那里向子组件发送数据。这取决于:如果这两个调用真的是独立的(所以不管哪一个结果首先出现),那么将它们放在子组件中可能会更好。但是,如果你的应用程序不断增长,那么最好尝试在组件树中保持尽可能高的状态,使尽可能多的子组件保持纯状态(即无状态)。在您的情况下,我会将它们保留在父级中:通过将所有逻辑保留在父级中,多个呈现是保持代码清晰易懂的低代价。谢谢,我会将它们保留在父级中。并且完全依赖于单击的元素,所以它是有意义的。
    handleParentClick(tid,sifUser) {
        this.setState({
            tid : tid , 
            sifUser : sifUser
        },
        () => {
            this.loadChildRequestsFromServer();
            this.loadUserDataFromServer();
        });
    }