在React中,默认情况下,如果父组件数据发生了更新,那么所有子组件都会无条件更新 !!!!!!
通过shouldComponentUpdate()retrun fasle 来判断阻止 Header 组件做无意义的更新
shouldComponentUpdate()并不是每次都需要使用,而是需要的时候才会优化

  1. class App extends React.Component {
  2. constructor () {
  3. this.state = { list: [] }
  4. }
  5. render () {
  6. return (
  7. <div>
  8. {/* 当list数据发生变化时,Header组件也会更新,调用 render() */}
  9. <Header />
  10. <List data={this.state.list}
  11. </div>
  12. )
  13. }
  14. }

shouldComponentUpdate()判断中,有一个有意思的问题,解释为什么 React setState() 要用不可变值
**

  1. // 父组件中
  2. changeList () {
  3. this.state.list.push({id: 2})
  4. this.setState({
  5. list: this.state.list
  6. })
  7. }
  8. // 子组件中
  9. import _ from 'lodash'
  10. shouldComponentUpdate(nextProps, nextState) {
  11. // 数组深度比较(一次性递归到底,耗费性能,工作中慎用)深比较
  12. if (_.isEqual(nextProps.list, this.props.list)) {
  13. return false // 相等,不渲染
  14. }
  15. return true // 不相等,渲染
  16. }

PureComponent & memo

  • class类组件中用PureComponent,无状态组件(无状态)中用memo
  • PureComponent, SCU中实现了浅比较
  • 浅比较已使用大部分情况(尽量不要做深度比较

PureComponent 与普通 Component 不同的地方在于,PureComponent自带了一个shouldComponentUpdate(),并且进行了浅比较

  1. // memo用法
  2. function MyComponent (props) {
  3. /* 使用 props 渲染 */
  4. }
  5. // areEqual 也可不传
  6. function areEqual(prevProps, nextProps) {
  7. if (prevProps.seconds===nextProps.seconds) {
  8. return true
  9. } else {
  10. return false
  11. }
  12. }
  13. export default React.memo(MyComponent, areEqual)