• React中setState方法详细讲解


    setState跟新数据是同步还是异步?

    setState跟新数据是异步的。
    如何用代码表现出来是异步的。
    点击按钮更新数据,然后去打印这个值看一下
    

    setState跟新数据是异步的

    class Father extends React.Component{
      state = {
       num:0
      }
      addHandler = () => { 
        this.setState({
          num: 100
        })
        console.log('state中的值',this.state.num)
      }
      render() { 
        return (
          <div>
            <button onClick={this.addHandler}>新增</button>
            <p>显示的值 {this.state.num }</p>
          </div>
        )
      }
    }
    ReactDOM.render(
      <Father></Father>,
      document.getElementById('root')
    )
    

    我们发现

    当我们使用setState更新数据时候,
    然后立刻去获取更新后的值,我们发现不是我们更新后的值。
    而是更新前的值。
    这就说明了setState跟新数据是异步的
    

    因此需要注意的点

    由于 setState 跟新数据是异步的。
    因此 setState 后面的代码不要依赖于setState前面的。
    

    同一个方法多次调用 setState会怎么样

    class Father extends React.Component{
      state = {
       num:0
      }
      addHandler = () => { 
        <!-- 第一调用 -->
        this.setState({
          num: this.state.num+1
        })
        console.log('state中的值', this.state.num)
        
        <!-- 第二次调用 -->
        this.setState({
          num: this.state.num + 1
        })
        console.log('state中的值', this.state.num)
      }
      render() { 
        return (
          <div>
            <button onClick={this.addHandler}>新增</button>
            <p>显示的值 {this.state.num }</p>
          </div>
        )
      }
    }
    

    我们的结论

    在同一个方法中我们调用了两次setState.
    但是最后界面上显示的不是20+1+1=2
    而是显示的1
    也就是说虽然多次调用setState,但是最终只会执行一次。 
    所以只会触发一次渲染界面。所以界面上显示的是1
    由于界面只触发一次,所以render函数也只会触发一次
    

    为什么多次调用setState最终只会触发一次渲染界面

    这样做的目的是为了性能的考虑。
    比如说你写了一个循环,循环了1000次;
    设计的时候如果让setState执行1000次;
    这样太浪费性能了。
    完全可以让开发者将最后的结果进行展示。
    
    所以React并不会将setState执行1000次
    而是只会执行一次。 render函数也只会执行一次。
    

    非要让setState多次执行怎么办?

    有没有这样的场景?
    第二次的setState需要依赖第一次的setState的结果
    举个简单的例子:第一次数字从0变为1,第二次1变为10
    这个时候我们怎么办了?
    比着急,有解决的办法
    

    setState 推荐语法

    setState((state, props) => { 
        参数state,表示最新的state
        参数props,表示最新的props
    })
    需要的是这种语法也是异步的哈
    

    使用推荐语法实现setState多次执行

    class Father extends React.Component{
      state = {
       num:0
      }
      addHandler = () => { 
        <!-- 在这个方法中我们多次调用了setState  -->
        this.setState((state, props) => { 
          // state 
          // props
          return {
            num: state.num+1
          }
        })
        this.setState((state, props) => {
          // state 
          // props
          return {
            num: state.num + 10
          }
        })
        console.log('state中的值', this.state.num)
      }
      render() { 
        return (
          <div>
            <button onClick={this.addHandler}>新增</button>
            <p>显示的值 {this.state.num }</p>
          </div>
        )
      }
    }
    

    setState第二个参数的诞生

    刚刚我们在前面发现console.log获取的值
    不是数据更新的后的值。
    而是初始值。我们也说了
    由于 setState 跟新数据是异步的。
    因此 setState 后面的代码不要依赖于setState前面的。
    如果我们想获取 setState更新后的值怎么办了?
    这个时候我们就需要使用setState的第二个参数。
    
    setState第二个参数的场景
    在状态更新完成(界面完成重新渲染)后立刻执行某一个操作
    ps:需要注意的的是不可以不会页面中的dom
    ps:需要注意的的是不可以不会页面中的dom
    this.setState(
        (state, props) => {
            return {}
        },
        ()=>{
            console.log('界面完成重新渲染)后立刻执行某一个操作')
        }
    )
    

    setState第二个参数的使用

    class Father extends React.Component{
      state = {
       num:0
      }
      addHandler = () => { 
        this.setState(
          (state, props) => {
            return {
              num: state.num + 1
            }
          },
          () => { 
            console.log('获取setState跟新后的值', this.state.num)
            console.log('dom节点',document.getElementById('#name') )
            console.log('cont', document.title)
          }
        )
      }
      render() { 
        return (
          <div>
            <button onClick={this.addHandler}>新增</button>
            <p id='name'>显示的值 {this.state.num }</p>
          </div>
        )
      }
    }
    ReactDOM.render(
      <Father></Father>,
      document.getElementById('root')
    )
    

  • 相关阅读:
    【JVM基础】堆
    【毕业设计】基于单片机的录音器设计与实现 - 物联网 嵌入式 stm32
    2-爬虫-代理池搭建、代理池使用(搭建django后端测试)、爬取某视频网站、爬取某视频网站、bs4介绍和遍历文档树
    【C++】类的封装 ③ ( 访问控制权限 )
    Python 爬虫基础入门知识
    CUDA学习笔记(十二) CUDA库简介
    [scratch][列表]全国青少年软件编程等级考试-四级-班级成绩处理
    Android Framework 框架层 | AMS 定义与知识点梳理
    C 语言 时间函数使用技巧(汇总)
    cart算法python实现:从CART算法中学习如何构建有效的决策树
  • 原文地址:https://www.cnblogs.com/IwishIcould/p/16410837.html