在网络上已经阅读了大量关于shouldComponentUpdate
和render
的文章,我想仔细检查在重新渲染组件(调用render
方法)以及何时重新获得正确的内容。 shouldComponentUpdate
被调用。
仅在收到新道具或有新状态的情况下,对文档(以及数十篇文章说)进行反应( shouldComponentUpdate
)。但是看来PureComponent
乍一看...
为了对此进行调查,我编写了示例应用程序:
import React, { Component } from 'react';
import './App.css';
import Hello from './Hello';
class App extends Component {
objWithName = { name: 'World' };
state = {
date: Date.now()
}
componentDidMount() {
setInterval(() => {
this.setState({ date: Date.now() });
}, 2000);
}
render() {
return (
<div className="App">
<p>Rendering timestamp {this.state.date}</p>
<Hello name={this.objWithName} />
</div>
);
}
}
export default App;
import React from 'react';
export default class Hello extends React.Component {
shouldComponentUpdate() {
console.log('shouldComponentUpdate called');
return true;
}
render() {
console.log('render called');
return <p>Hello {this.props.name.name}</p>
}
}
所以我的第一个问题是:这是真的吗?我的意思是:在以上代码段中,setInterval
中的父组件只是为了触发其更新而调用setState
,但是此状态在任何地方都没有使用。然后,子组件被重新渲染(称为render
)和shouldComponentUpdate
被调用,即使他没有任何改变(它没有收到任何新道具,也没有陈述)。我没有在React docs中找到对此行为的任何解释,所以我不确定它是如何工作的。而且,如果该子组件在(简单地渲染静态字符串)处没有任何输入道具,它也将被重新渲染。 sb可以解释吗?
第二个问题是:该组件接收到新的道具/状态是什么意思?这是否意味着对象值已更改(对于基元而言,只是新值,而对于对象而言,则是新引用)?
第三件事:假设应用程序中父级最主要的组件(例如App.js
)发生了更改(新属性或新状态),这是否意味着默认情况下,ALL做出反应当前渲染/安装的组件(甚至没有任何状态的叶子,也没有更改的道具)都将重新渲染?
答案 0 :(得分:0)
shouldComponentUpdate
中调用setState
,并在返回true(默认行为)时强制渲染(默认行为),并在不同时更新DOM。这是设计使然具有生命周期/流程。当shouldComponentUpdate
返回false时,可以避免不必要的,通常是昂贵的渲染处理(和DOM更新)。 PureComponent只是经过优化的,随时可用的,定义为shouldComponentUpdate
的组件,用于通过比较引用浅浅比较道具。React不在乎是否使用道具/状态,而不是使用可观察对象-您可以使用mobx。
新道具意味着任何改变-根据您的需要,吞咽或深入检查是shouldComponentUpdate
的责任。
是的,将更新所有子级(强制刷新虚拟DOM中的节点状态/视图)。这是一个快速/优化的过程(在虚拟树上运行),但是他们应该使用shouldComponentUpdate
来限制其重新呈现(以及最终的DOM更新)。