zoukankan      html  css  js  c++  java
  • React组件setState

    注意:

    1. 自定义组件首字母必须大写。这里是以函数表达式的方式定义子组件的。

    2. 使用 ES6 的 class 关键字创建的 React 组件,组件中的方法遵循与常规 ES6 class 相同的语法规则。这意味着这些方法不会自动绑定 this 到这个组件实例。 你需要显式地调用 .bind(this)

    一、setState(updater, [callback])

    1. updater的实质是一个函数

    setState((state, props) => ({quantity: state.quantity + 2}) )   // 返回的是状态改变对象,并与之前的state合并

    但更多的时候,我们使用其简写形式,传入的是一个对象

    setState({quantity: 2})

    如果新的状态不依赖原始state, 使用简写(对象)方式;如果新的状态依赖原始State, 使用函数方式写。

    2. setState() 并不总是立即更新组件。它会批量推迟更新。这使得在调用 setState() 后立即读取 this.state 成为了隐患。

    为了能正确获取更新后的state数据,在componentDidUpdate 或者在setState 的回调函数callback中去获取state值,保证获取的state是更新后的值。

    this.setState((state) => ({
        quantity: state.quantity + 1
        }), () => {
            console.log('after state update', state.quantity);
        }
    )

    3. setState()是同步的,还是异步的?

    react相关的回调(声明周期、react事件监听回调):异步
    
    其他异步回调(setTimeout, Promise.then事件回调 / await之后, DOM事件监听):同步

    4. 多次调用异步的setState, 无论调用多少次setState,只执行一次render.

    // 初始
    this.state = {
        count: 1
    }

    4.1 使用对象的方式(状态更新合并成一次)

    update1 = () =》 {
        this.setState({count : this.state.count +1});
        this.setState({count : this.state.count +1});
    }
    // render中得到的state.count = 2

    4.2 使用函数的形式(状态更新是多次进行的【updater 函数中接收的 state 和 props 都保证为最新】,render合并为一次)

    update2 = () => {
        this.setState((state) => ({
            count: state.count + 1
        })
        this.setState((state) => ({
            count: state.count + 1
        })
    }
    // render中的结果为3(加法执行了两次)

    4.3 混用对象形式和函数形式

    update3 = () => {
        // 先执行对象形式,后执行函数形式
        this.setState({count : this.state.count +1});
        this.setState((state) => ({
            count : state.count +1
        }));
    }    
    
    // render中的state.count = 3
    
    update4 = () => {
    //先执行函数形式, 再执行对象形式
        this.setState((state) => ({
            count : state.count +1
        }));
        this.setState({count : this.state.count +1});
    }    
    // render中的state.count = 2

    拓展:面试题

    class Test extends React.Component {
        state = {
          count: 0
        };
        // handleClick = () => {};
        componentDidMount() {
          // 异步
          this.setState({
            count: this.state.count + 1
          });
          this.setState({
            count: this.state.count + 1    // 1
          });
          console.log(this.state.count);    // 2==>0
          // 异步
          this.setState(state => ({ count: state.count + 1 }));   // 2
          this.setState(state => ({ count: state.count + 1 }));   // 3
          console.log(this.state.count);    // 3==>0
      
          setTimeout(() => {
            this.setState({ count: this.state.count + 1 });   //6
            console.log("timeout", this.state.count);          // 10==>6
      
            this.setState({ count: this.state.count + 1 });    //7
            console.log("timeout", this.state.count);       //  12==>7
          });
      
          Promise.resolve().then(value => {
            this.setState({ count: this.state.count + 1 });  // 4
            console.log("promise", this.state.count);     // 6==>4
      
            this.setState({ count: this.state.count + 1 });   //5
            console.log("promise", this.state.count);    // 8==>5
          });
        }
        render() {
          const { count } = this.state;
          console.log("render", count);   // 1==>0  4==>3 5==>4 7==>5  9==>6  11=>7
          return (
            <div>
              <p>{count}</p>
              {/* <button onClick={() => this.handleClick}>更新</button> */}
            </div>
          );
        }
      }

    注意:多个setState执行后,他们的组合结果一次性地传递给render进行重新渲染。

  • 相关阅读:
    VB Treeview控件 介绍与使用
    基于V4L2的视频驱动开发
    Jlinkv8 灯不亮重新烧写固件的办法
    使用JLink间接烧写S3C2410、S3C2440开发板Nor、Nand Flash的方法
    linux 开机自动执行脚本或者一些指定的程序
    FrameBuffer编程二(简单程序下)
    c语言内存分配函数
    FrameBuffer编程二(简单的程序上)
    FrameBuffer编程一(数据结构)
    mmap函数介绍
  • 原文地址:https://www.cnblogs.com/ceceliahappycoding/p/12208624.html
Copyright © 2011-2022 走看看