• React--组件更新机制&组件性能优化


    1.1setState{}的两个作用:

    • 修改state
    • 更新组件(UI)

    1.2过程:父组件重新渲染时,也会重新渲染子组件。但只会渲染当前组件子树(当前组件及其所有子组件)

     2.减轻state

    1. class Hello extends Component{
    2. componentDidMount(){
    3. //timeId存储到this中,而不是state中
    4. this.timeId = setInterval(()=>{},2000)
    5. }
    6. commponentWillUnmount(){
    7. clearInterval(this.timerId)
    8. }
    9. render(){...}
    10. }
    • 减轻state:只存储跟组件渲染相关的数据(比如:count/列表数据/loading等)
    • 注意:不用做渲染的数据不要放在state中,比如定时器id等
    • 对于这种需要在多个方法中用到的数据,应该放在this中

    3.避免不必要的重新渲染

    • 组件更新机制:父组件更新会引起子组件也被更新,这种思路很清晰
    • 问题:子组件没有任何变化时也会重新渲染
    • 如何避免不必要的重新渲染呢?
    • 解决方法:使用钩子函数shouldComponentUpdate(nextProps,nextState)
    • 作用:通过返回值决定该组件是否重新渲染,返回true表示重新渲染,false表示不重新渲染 
    • 触发时机:更新阶段的钩子函数,组件重新渲染前执行(shouldComponentUpdate-->render)
    • 随机数案例
    1. import { number } from 'prop-types';
    2. import React from 'react';
    3. import ReactDOM from 'react-dom';
    4. // import MyEditor from './components/MyEditor';
    5. class App extends React.Component{
    6. state={
    7. number:0
    8. }
    9. handleClick = () =>{
    10. this.setState(()=>{
    11. return{
    12. number: Math.floor(Math.random()*3)
    13. }
    14. })
    15. }
    16. shouldComponentUpdate(nextprops,nextState){
    17. console.log('最新的state:',nextState)
    18. console.log('this.state:',this.state)
    19. //返回false,阻止组件重新渲染
    20. return false
    21. }
    22. render(){
    23. return(
    24. <div>
    25. <h1>随机数:{this.state.number}h1>
    26. <button onClick={this.handleClick}>重新生成button>
    27. div>
    28. )
    29. }
    30. }
    31. ReactDOM.render(<App>App>,
    32. document.getElementById('root'))

    改进:

    1. import { number } from 'prop-types';
    2. import React from 'react';
    3. import ReactDOM from 'react-dom';
    4. // import MyEditor from './components/MyEditor';
    5. class App extends React.Component{
    6. state={
    7. number:0
    8. }
    9. handleClick = () =>{
    10. this.setState(()=>{
    11. return{
    12. number: Math.floor(Math.random()*3)
    13. }
    14. })
    15. }
    16. shouldComponentUpdate(nextprops,nextState){
    17. console.log('最新的state:',nextState)
    18. console.log('this.state:',this.state)
    19. // //返回false,阻止组件重新渲染
    20. // return false
    21. if(nextState.number === this.state.number) return false
    22. else return true
    23. }
    24. render(){
    25. console.log('重新渲染')
    26. return(
    27. <div>
    28. <h1>随机数:{this.state.number}h1>
    29. <button onClick={this.handleClick}>重新生成button>
    30. div>
    31. )
    32. }
    33. }
    34. ReactDOM.render(<App>App>,
    35. document.getElementById('root'))

    更加简洁的写法:if nextState.number !== this.state.number 

    4.使用另外一个参数(nextProps) 

    1. import { number } from 'prop-types';
    2. import React from 'react';
    3. import ReactDOM from 'react-dom';
    4. // import MyEditor from './components/MyEditor';
    5. class App extends React.Component{
    6. state={
    7. number:0
    8. }
    9. handleClick = () =>{
    10. this.setState(()=>{
    11. return{
    12. number: Math.floor(Math.random()*3)
    13. }
    14. })
    15. }
    16. render(){
    17. // console.log('重新渲染')
    18. return(
    19. <div>
    20. <NumberBox number={this.state.number}>NumberBox>
    21. <button onClick={this.handleClick}>重新生成button>
    22. div>
    23. )
    24. }
    25. }
    26. class NumberBox extends React.Component{
    27. shouldComponentUpdate(nextProps,nextState){
    28. console.log('最新的props:',nextProps,',当前props',this.props)
    29. return nextProps.number !== this.props.number
    30. }
    31. render(){
    32. console.log('重新渲染')
    33. return <h1>随机数:{this.props.number}h1>
    34. }
    35. }
    36. ReactDOM.render(<App>App>,
    37. document.getElementById('root'))

  • 相关阅读:
    联邦学习系统攻击与防御技术
    【实战】学习 Electron:构建跨平台桌面应用
    README.md文件使用
    一文掌握 Java8 Stream 中 Collectors 的 24 个操作
    spring5.0源码解析 Aop 04 配置通知器
    Intent传大数据的深入分析
    Monaco Editor教程(十六):缩略图minimap的配置详解
    CentOS密码重置
    java笔试面试题含答案总结六
    大数据必学Java基础(十四):Java中的运算符
  • 原文地址:https://blog.csdn.net/weixin_53052268/article/details/126145963