zoukankan      html  css  js  c++  java
  • 【React 6/100】 React原理 | setState | JSX语法转换 | 组件更新机制

    ****关键字 | setState | JSX语法转换 | 组件更新机制

    组件更新机制

    • setState() 的两个作用
      • 修改state
      • 更新组件
    • 过程:父组件重新渲染时,也会重新渲染子组件,但只会渲染当前组件子树(当前组件以其所有子组件)

    组件性能优化

    减轻state
    • 减轻state:只存储跟组件渲染相关的数据(比如:count/ 列表数据 /loading等)
    • 注意:不用做渲染的数据不要放在state中
    • 对于这种需要在多个方法中用到的数据,应该放到this中
    避免不必要的重新渲染
    • 组件更新机制:父组件更新会引起子组件也被更新,这种思路很清晰
    • 问题:子组件没有任何变化时也会重新渲染
    • 如果避免不必要的重新渲染?
    • 解决方式:使用钩子函数 shouldComponentUpdate(nextProps, nextState)
      • 在这个函数中,nextProps和nextState是最新的状态以及属性
    • 作用:这个函数有返回值,如果返回true,代表需要重新渲染,如果返回false,代表不需要重新渲染
    • 触发时机:更新阶段的钩子函数,组件重新渲染前执行(shouldComponentUpdate => render)
    // 生成随机数
    class RandomNumber extends React.Component {
        state = {
            number: 0
        };
        btnHandlerClicked = () => {
            this.setState((state, props) => {
              return {
                  number: Math.ceil(Math.random() * 3)
              }
            })
        };
    
        // 两次生成的随机数可能相同,如果相同就没必要重新渲染
     	// 将要更新UI的时候会执行这个钩子函数
        shouldComponentUpdate(nextProps, nextState, nextContext) {
            console.log('nextProps: ',nextProps ,' -- nextState: ' , nextState , ' -- nextContext' , nextContext , ' -- this.state', this.state);
            if(nextState.number !== this.state.number || nextProps.sendnumber !== this.props.sendnumber){
                return true;
            }
            return false;
        }
    
        render() {
            console.log('render -- ');
            return (
                <div>
                    <h2>随机数: {this.state.number}</h2>
                    <button onClick={this.btnHandlerClicked}>clickedMe create random number</button>
                </div>
            )
        }
    }
    
    // 渲染
    ReactDOM.render(<RandomNumber/>, document.getElementById('root'));
    

    纯组件

    作用以及使用
    • 纯组件: PureComponent 与 React.Component 功能相似

    • 区别: PureComponent 内部自动实现了 shouldComponentUpdate钩子,不需要手动比较

    • 原理:纯组件内部通过分别比对前后两次 props和state的值,来决定是否重新渲染组件

      // 生成随机数
      class RandomNumber extends React.PureComponent {
          state = {
              number: 0
          };
          btnHandlerClicked = () => {
              this.setState((state, props) => {
                  return {
                      number: Math.ceil(Math.random() * 3)
                  }
              })
          };
      
          render() {
              console.log('render -- ');
              return (
                  <div>
                      <h2>随机数: {this.state.number}</h2>
                      <button onClick={this.btnHandlerClicked}>clickedMe create random number</button>
                  </div>
              )
          }
      }
      
      // 渲染
      ReactDOM.render(<RandomNumber sendnumber={1234}/>, document.getElementById('root'));
      
    实现原理
    • 说明:纯组件内部的对比是 shallow compare(浅层对比)
    • 对于值类型来说:比较两个值是否相同
    • 引用类型:只比对对象的引用地址是否相同
    • 注意:state 或 props 中属性值为引用类型时,应该创建新数据,不要直接修改原数据
    // 正确做法:创建新对象
    const newObj = { ...this.state.obj, number: Math.floor(Math.random() * 3) }
    this.setState(() => {
        return {
            obj: newObj
        }
    })
    
    // 错误演示:直接修改原始对象中属性的值
    const newObj = this.state.obj;
    newObj.number = Math.floor(Math.random() * 3)
    
    this.setState(() => {
        return {
            obj: newObj
        }
    }) 
    
  • 相关阅读:
    TP之Model(select(),add())
    TP之空操作及View模块
    ThinkPHP之初识
    smarty引擎之练习
    领先环境HTML
    php流程
    分页
    弹窗
    邮箱项目
    TP框架修改操作
  • 原文地址:https://www.cnblogs.com/YangxCNWeb/p/11994536.html
Copyright © 2011-2022 走看看