1. 性能问题
- 只要执行setState(), 即使不改变状态数据, 组件也会重新render() ===> 效率低
- 只有当前组件重新render(), 就会自动重新render子组件, 纵使子组件没有用到父组件的任何数据====》 效率低
提高效率的做法:只有当组件的state或者props发生改变时才重新render()
原因: Component中的shouldComponentUpdate()总是返回true
class App extends Component {state = {count:10}add = () =>{this.setState(state =>({ count: state.count + 1}))}render() {const { count} = this.state;return (<div className='parent'><h2>我是APP组件</h2><h3>count当前的值是:{count}</h3><button type="button" onClick={this.add}>+</button><hr/><Child/>{/* <Child add={this.add} count={count}/> */}</div>);}}class Child extends Component {render() {console.log('子组件调用render方法')return (<div className='child'><h2>我是Child组件</h2><h3>count当前的值是:{this.props?.count}</h3><button onClick={this.props?.add}>修改父组件的值</button></div>);}}export default App;
2. shouldComponentUpdate
重写shouldComponentUpdate()方法. 比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false
import React, { Component } from 'react'export default class Parent extends Component {state={carName:'迈巴赫'}changeCar = () => {this.setState({carName:'宝马'})}shouldComponentUpdate(nextProps, nextState){console.log(nextProps, nextState);return this.state.carName !== nextState.carName}render() {console.log('parent render');return (<div><div>我喜欢的车是:{this.state.carName}</div><button onClick={this.changeCar}>换车</button><Child carName='奥迪A6'/></div>)}}class Child extends Component{shouldComponentUpdate(nextProps, nextState){console.log(nextProps, nextState);return this.props.carName !== nextProps.carName}render() {console.log('Child render');return (<div><div>我喜欢的车是:{this.props.carName}</div></div>)}}
这样存在的问题是, 如果state中的值是一个对象, 并且属性比较多, 那么比较的时候就比较麻烦。
3. PureComponent
使用PureComponent:重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true.
import React, { Component, PureComponent } from 'react'export default class Parent extends PureComponent {state={carName:'迈巴赫'}changeCar = () => {this.setState({carName:'宝马'})}render() {console.log('parent render');return (<div><div>我喜欢的车是:{this.state.carName}</div><button onClick={this.changeCar}>换车</button><Child carName='奥迪A6'/></div>)}}class Child extends PureComponent{render() {console.log('Child render');return (<div><div>我喜欢的车是:{this.props.carName}</div></div>)}}
add = () =>{// this.setState(state =>({ count: state.count + 1}))const obj = this.state;obj.count += 5this.setState(obj)console.log(this.state === obj) //true}
上面这种方式是新建一个对象, 而下面这种方式是在原对象上进行修改的。
注意:
- 只是进行state和props数据的浅比较, 如果只是数据对象内部数据变了, 返回false
- 不要直接修改state数据, 而是要产生新数据
项目中一般使用PureComponent来优化。
