Xle*_*lee 8 performance components reactjs react-dom
使用PureComponent来改善React中的渲染性似乎是一种常见的技术.但是,使用具有子项作为道具的PureComponent时似乎并非如此.
class App extends React.PureComponent {
render() {
console.log('re-render')
return <div>{this.props.children}</div>
}
}
const render = () => {
ReactDOM.render(
<App>
<div />
</App>,
document.getElementById('app')
)
setTimeout(render, 1000)
}
render()
Run Code Online (Sandbox Code Playgroud)
结果是控制台每1秒保持记录"重新渲染".似乎children(<div />)是上面App组件的唯一支柱并且永远不会改变,为什么App仍然会被重新渲染?
注意:如果有任何混淆,问题是相同的,为什么上面的PureComponent的SCU(shouldComponentUpdate)钩子返回true,因为没有道具似乎改变了?
这里发生的是你实际上正在调用ReactDOM.render(),Page(或App,我认为你这里有一个拼写错误)组件会触发它的render()功能而不管使用Component或PureComponent.
PureComponent可以帮助减少不必要的渲染的方式是当有一个prop更改时,PureComponent将进行浅层比较this.props并nextProps确定此PureComponent是否需要调用render().
我刚刚为你做了这个例子:
class App extends React.PureComponent {
state = {value: 0}
componentDidMount() {
setInterval(() => {
this.setState({value: Math.random()})
}, 1000)
}
render() {
return (
<div>
<PureChild value="fixed value"/>
<ImpureChild value="fixed value"/>
</div>
)
}
}
class PureChild extends React.PureComponent {
render() {
console.log('rendering PureChild')
return <div>{this.props.value}</div>
}
}
class ImpureChild extends React.Component {
render() {
console.log('rendering ImpureChild')
return <div>{this.props.value}</div>
}
}
Run Code Online (Sandbox Code Playgroud)
注意以下几点:
<App />更改value状态,因此它重新呈现,导致其所有子项也重新呈现.<PureChild />是一个PureComponent,它对旧的道具和传入的新道具进行浅层比较,并且通知两个道具都是"fixed value",因此它不会触发渲染!如果你运行这个代码并打开控制台,你会看到每1秒'渲染一次ImpureChild',但'渲染PureChild'只会出现一次.
console.log(<div /> === <div />) // false
Run Code Online (Sandbox Code Playgroud)
每次重绘时<App />,都会创建一个新的 React ElementReact.createElement(div, null),因此与JSX中的外观相同。this.props.childrennextProps.children
实际上,真正的问题是props.children每次父级重新渲染并且React.PureComponent通过引用包含不变性来比较props时,引用的引用(否则为值,如果是原始类型)就会发生变化。
| 归档时间: |
|
| 查看次数: |
2933 次 |
| 最近记录: |