1. 性能问题

  • 只要执行setState(), 即使不改变状态数据, 组件也会重新render() ===> 效率低
  • 只有当前组件重新render(), 就会自动重新render子组件, 纵使子组件没有用到父组件的任何数据====》 效率低

提高效率的做法:只有当组件的state或者props发生改变时才重新render()
原因: Component中的shouldComponentUpdate()总是返回true

  1. class App extends Component {
  2. state = {
  3. count:10
  4. }
  5. add = () =>{
  6. this.setState(state =>({ count: state.count + 1}))}
  7. render() {
  8. const { count} = this.state;
  9. return (
  10. <div className='parent'>
  11. <h2>我是APP组件</h2>
  12. <h3>count当前的值是:{count}</h3>
  13. <button type="button" onClick={this.add}>+</button>
  14. <hr/>
  15. <Child/>
  16. {/* <Child add={this.add} count={count}/> */}
  17. </div>
  18. );
  19. }
  20. }
  21. class Child extends Component {
  22. render() {
  23. console.log('子组件调用render方法')
  24. return (
  25. <div className='child'>
  26. <h2>我是Child组件</h2>
  27. <h3>count当前的值是:{this.props?.count}</h3>
  28. <button onClick={this.props?.add}>修改父组件的值</button>
  29. </div>
  30. );
  31. }
  32. }
  33. export default App;

2. shouldComponentUpdate

重写shouldComponentUpdate()方法. 比较新旧stateprops数据, 如果有变化才返回true, 如果没有返回false

  1. import React, { Component } from 'react'
  2. export default class Parent extends Component {
  3. state={
  4. carName:'迈巴赫'
  5. }
  6. changeCar = () => {
  7. this.setState({
  8. carName:'宝马'
  9. })
  10. }
  11. shouldComponentUpdate(nextProps, nextState){
  12. console.log(nextProps, nextState);
  13. return this.state.carName !== nextState.carName
  14. }
  15. render() {
  16. console.log('parent render');
  17. return (
  18. <div>
  19. <div>我喜欢的车是:{this.state.carName}</div>
  20. <button onClick={this.changeCar}>换车</button>
  21. <Child carName='奥迪A6'/>
  22. </div>
  23. )
  24. }
  25. }
  26. class Child extends Component{
  27. shouldComponentUpdate(nextProps, nextState){
  28. console.log(nextProps, nextState);
  29. return this.props.carName !== nextProps.carName
  30. }
  31. render() {
  32. console.log('Child render');
  33. return (
  34. <div>
  35. <div>我喜欢的车是:{this.props.carName}</div>
  36. </div>
  37. )
  38. }
  39. }

这样存在的问题是, 如果state中的值是一个对象, 并且属性比较多, 那么比较的时候就比较麻烦。

3. PureComponent

使用PureComponent:重写了shouldComponentUpdate(), 只有stateprops数据有变化才返回true.

  1. import React, { Component, PureComponent } from 'react'
  2. export default class Parent extends PureComponent {
  3. state={
  4. carName:'迈巴赫'
  5. }
  6. changeCar = () => {
  7. this.setState({
  8. carName:'宝马'
  9. })
  10. }
  11. render() {
  12. console.log('parent render');
  13. return (
  14. <div>
  15. <div>我喜欢的车是:{this.state.carName}</div>
  16. <button onClick={this.changeCar}>换车</button>
  17. <Child carName='奥迪A6'/>
  18. </div>
  19. )
  20. }
  21. }
  22. class Child extends PureComponent{
  23. render() {
  24. console.log('Child render');
  25. return (
  26. <div>
  27. <div>我喜欢的车是:{this.props.carName}</div>
  28. </div>
  29. )
  30. }
  31. }
  1. add = () =>{
  2. // this.setState(state =>({ count: state.count + 1}))
  3. const obj = this.state;
  4. obj.count += 5
  5. this.setState(obj)
  6. console.log(this.state === obj) //true
  7. }

上面这种方式是新建一个对象, 而下面这种方式是在原对象上进行修改的。
注意:

  • 只是进行stateprops数据的浅比较, 如果只是数据对象内部数据变了, 返回false
  • 不要直接修改state数据, 而是要产生新数据

项目中一般使用PureComponent来优化。