优化无用渲染
前述
shouldComponentUpdatePure ComponentReact.memo
描述
每当我们设置 React 中某个 state 时,页面都会重新渲染。即使这个 state 的值没有发生改变,也会触发重新渲染,导致页面性能被占用。
实践
类 - shouldComponentUpdate && PureComponent
普通例子 TestC:
import React from 'react';
class TestC extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
}
}
componentWillUpdate(nextProps, nextState) {
console.log('componentWillUpdate')
}
componentDidUpdate(prevProps, prevState) {
console.log('componentDidUpdate')
}
render() {
return (
<div >
{this.state.count}
<button onClick={()=>this.setState({count: 1})}>Click Me</button>
</div>
);
}
}
export default TestC;
执行这个页面可以发现,每次点击按钮,页面都会重绘
shouldComponentUpdate
用 shouldComponentUpdate 重写之前的 TestC 组件:
import React from 'react';
class TestC extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
}
}
componentWillUpdate(nextProps, nextState) {
console.log('componentWillUpdate')
}
componentDidUpdate(prevProps, prevState) {
console.log('componentDidUpdate')
}
// 在 compoenentDidUpdate 中拦截重绘
shouldComponentUpdate(nextProps, nextState) {
if (this.state.count === nextState.count) {
return false
}
return true
}
render() {
return (
<div>
{ this.state.count }
<button onClick = {
() => this.setState({ count: 1 }) }> Click Me </button>
</div>
);
}
}
export default TestC
由于在 shouldComponentUpdate 中进行了拦截,所以当 state 没有发生改变的时候,不会触发组件的重绘
PureComponent
React 在 v15.5 引入了 PureComponent,React 在进行组件更新时,如果发现这个 Component 是一个 PureComponent,会将组件现在的 state 和 props 和其下一个 state 和 props 进行浅比较,如果它们的值没有变化,就不会进行更新。
import React from 'react'
class TestC extends React.PureComponent {
constructor(props) {
super(props)
this.state = {
count: 0
}
}
componentWillUpdate(nextProps, nextState) {
console.log('componentWillUpdate')
}
render() {
return (
<div>
{ this.state.count }
<button onClick = {
() => this.setState({ count: 1 })
}> Click Me </button>
</div>
)
}
}
export default TestC
可以看到上面 PureComponent 实现了和我们在 shouldComponentUpdate 中实现的功能一样。
但是,我曾遇到一个坑,如果 state 树深度超过 2 可能会出现无论如何改变 state 都无法触发重绘函数
函数组件 - React.memo
函数组件和类不同,没有 shouldComponentUpdate 这些属性
普通例子 TestC:
import React from 'react';
const TestC = (props) => {
console.log(`Rendering TestC :` props)
return (
<div>
{props.count}
</div>
)
}
export default TestC;
// App.js
<TestC count={5} />
React.memo
React.memo 是 React v16.6 引入的新特性,它的作用和React.PureComponent类似,是用来控制函数组件的重新渲染的。React.memo(...) 其实就是函数组件的React.PureComponent。
import React from 'react';
let TestC = (props) => {
console.log('Rendering TestC :', props)
return (
<div>
{ props.count }
</>
)
}
TestC = React.memo(TestC);
export default TestC;
此时,当我们传入 props.count 没有发生改变时,便不会再重绘
结论
React.PureComponent是给ES6的类组件使用的React.memo(...)是给函数组件使用的React.PureComponent减少ES6的类组件的无用渲染React.memo(...)减少函数组件的无用渲染
Last updated
Was this helpful?