请选择 进入手机版 | 继续访问电脑版
MSIPO技术圈 首页 IT技术 查看内容

【前端知识】React 基础巩固(二十二)——setState()函数

2023-07-13

React 基础巩固(二十二)——setState()函数

setState 的三种不同用法

import React, { Component } from "react";

export class App extends Component {
  constructor() {
    super();

    this.state = {
      message: "outman",
      counter: 0,
    };
  }

  changeText() {
    // 1.基本使用
    // this.setState({
    //   message: "outman chen",
    // });

    // 2.setState可以传入一个回调函数
    // 优点1:可以在回调函数中编写新的state的逻辑
    // 优点2:当前的回调函数会将之前的state的props传递进来
    // this.setState((state, props) => {
    //   return {
    //     message: "outman callback",
    //   };
    // });

    // 3.setState在React的事件处理中是一个异步调用
    // 如果希望在数据更新之后(数据合并),获取到对应的结果执行一些逻辑代码
    this.setState(
      {
        message: "outman change",
      },
      () => {
        console.log("+++++", this.state.message);
      }
    );
    console.log("------", this.state.message);
  }

  increment() {}

  render() {
    const { message, counter } = this.state;
    return (
      <div>
        <h2>message:{message}</h2>
        <button onClick={(e) => this.changeText()}>修改文本</button>
        <h2>当前计数:{counter}</h2>
        <button onClick={(e) => this.increment()}>counter + 1</button>
      </div>
    );
  }
}

export default App;

setState 为什么设计成异步?

  • setState 设计为异步,可以显著的提升性能
    • 如果每次调用 setState 都进行一次更新,那么意味着 render 函数会被频繁调用,界面重新渲染,这样效率非常低
    • 最好的办法应该是获取到多个更新之后,进行批量更新
  • 如果同步更新了 state,但是还没有执行 render 函数,那么 state 和 props 不能保持同步
    • state 和 props 不能保持一致性,会在开发中产生很多问题
import React, { Component } from "react";

function Hello(props) {
  return <h2>{props.message}</h2>;
}

export class App extends Component {
  constructor() {
    super();

    this.state = {
      message: "outman",
      counter: 0,
    };
  }

  componentDidMount() {
    // 1.请求一
    // 2.请求二
    // 3.请求三
  }

  changeText() {
    this.setState({
      message: "outman change text",
    });
    // 如果同步更新了 state,但是还没有执行 render 函数,那么 state 和 props 不能保持同步
    console.log(this.state.message);
  }

  increment() {
    // console.log("---直接set,累加counter后为1---");
    // this.setState({
    //   counter: this.state.counter + 1,
    // });
    // this.setState({
    //   counter: this.state.counter + 1,
    // });
    // this.setState({
    //   counter: this.state.counter + 1,
    // });

    // console.log("---回调方式,通过state获取每次新的值,累加counter后为3---");
    this.setState((state) => {
      return {
        counter: state.counter + 1,
      };
    });
    this.setState((state) => {
      return {
        counter: state.counter + 1,
      };
    });
    this.setState((state) => {
      return {
        counter: state.counter + 1,
      };
    });
  }
  render() {
    console.log("render函数被执行");
    const { message, counter } = this.state;
    return (
      <div>
        <h2>message:{message}</h2>
        <button onClick={(e) => this.changeText()}>修改文本</button>
        <h2>当前计数:{counter}</h2>
        <button onClick={(e) => this.increment()}>counter + 1</button>

        <Hello message={message} />
      </div>
    );
  }
}

export default App;

setState 一定是异步的吗?

在 React18 之前

  • 在组件生命周期或 React 合成事件中,setState 是异步
  • 在 setTimeout 或者原生 dom 事件中,setState 是同步

在 React18 之后

  • 默认所有操作都放到了批处理中,均为异步
import React, { Component } from "react";
import { flushSync } from "react-dom";

function Hello(props) {
  return <h2>{props.message}</h2>;
}

export class App extends Component {
  constructor() {
    super();

    this.state = {
      message: "outman",
      counter: 0,
    };
  }

  componentDidMount() {
    // 1.请求一
    // 2.请求二
    // 3.请求三
  }

  changeText() {
    // 异步
    // this.setState({
    //   message: "异步操作",
    // });
    // console.log(this.state.message);

    // 同步
    // 在react18之前,这是同步操作
    // 在react18之后,所有处理均变为批处理,为异步操作
    // setTimeout(() => {
    //   this.setState({
    //     message: "同步操作",
    //   });
    //   console.log(this.state.message);
    // }, 0);

    // 在react18之后,用flushSync实现同步
    setTimeout(() => {
      flushSync(() => {
        this.setState({
          message: "同步操作",
        });
      });

      console.log(this.state.message);
    }, 0);
  }

  increment() {}
  render() {
    console.log("render函数被执行");
    const { message, counter } = this.state;
    return (
      <div>
        <h2>message:{message}</h2>
        <button onClick={(e) => this.changeText()}>修改文本</button>
        <h2>当前计数:{counter}</h2>
        <button onClick={(e) => this.increment()}>counter + 1</button>

        <Hello message={message} />
      </div>
    );
  }
}

export default App;

相关阅读

热门文章

    手机版|MSIPO技术圈 皖ICP备19022944号-2

    Copyright © 2024, msipo.com

    返回顶部