setState

作者: wpLishuai | 来源:发表于2020-10-10 15:38 被阅读0次

State 是私有的,完全受控于当前组件

组件的state只能在contructor构造函数中初始化,并且在constructor中只能赋值初始化不能使用setState

修改state的值只能通过setState函数,如果直接给state的属性赋值无效,并且报一个警告

this.state.counter += 1;//  Do not mutate state directly. Use setState()  react/no-direct-mutation-state

state中的数据都是参数React数据流的,都是响应式的,不重写 shouldCompoentUpdate函数时state中的值变化了都是重新渲染页面的。

shouldComponentUpdate默认返回true,只要props和state中的值变化了都会触发页面从新渲染

setState方法可以是异步的也可以是同步

在react的合成事件和生命周期中是异步的。

import React, { Component } from 'react'

export default class App extends Component {
  constructor() {
    super();
    this.state = {
      message: 'hello react'
    }
  }

  changeText() {
    this.setState({
      message: "你好啊,李银河"
    });
    console.log(this.state.message);// hello react
  }

  render() {
    console.log("render ....");
    return (
      <div>
        <h2>{this.state.message}</h2>
        <button onClick={e => this.changeText()}>改变文本</button>
      </div >
    )
  }
}

window.setIntervalsetTimeout和原生事件中(如:document.addEventLisenter('',()=>{}))是同步的

import React, { Component } from 'react'

export default class App extends Component {
  constructor() {
    super();
    this.state = {
      message: 'Hello World!',
      counter: 0
    }
  }
  render() {
    return (
      <div>
        <h2>{this.state.message}</h2>
        <button onClick={e => this.changeText(e)}>改变文本</button>

        <button id="btn">改变文本2</button>
        <button onClick={e => this.changeText3(e)}>累加+1</button>
      </div>
    )
  }

  componentDidMount() {
    document.getElementById("btn").addEventListener("click", (e) => {
      this.setState({
        message: "你好啊,李银河 sync"
      });
      console.log("原生事件中修改state的值,", this.state.message);
    })
  }

  changeText(e) {
    setTimeout(() => {
      this.setState({
        message: "你好啊,李银河 async"
      });
      console.log("同步更新state的值,setTimeout ", this.state.message);
    }, 1000);
  }

  changeText3(e) {
    window.setInterval(() => {
      this.setState({
        counter: this.state.counter + 1
      });
      console.log("同步更新state的值,setInterval ", this.state.counter);
    }, 1000);
  }
}

setState异步时,可以将setState视为请求而不是立即更新组件的命令,这些请求会拍入队列,从性能考虑批量更新组件效率会更高。因此调用setState之后立即获取更改后的值会存在问题。

异步情况下无法直接获取修改后的值,但是有两种方式获取修改过后的值

  • componentDidUpdate中获取修改后的值

  • setState({},()=>{})的回调函数中获取

import React, { Component } from 'react'

export default class App extends Component {
  constructor() {
    super();
    this.state = {
      counter: 0
    }
  }

  increment = () => {
    // this.state.counter += 1;
    this.setState({
      counter: this.state.counter + 1
    })
  }
  render() {
    return (
      <div>
        <h2>计数器:{this.state.counter}</h2>
        <button onClick={this.increment}>+1</button>
      </div>
    )
  }
}

setState传入的是一个对象的时候实际上调用的是Object.assign()方法,React的源码


当多次调用setState的时候

increment = () => {
  this.setState({
    counter: this.state.counter + 1
  });
  this.setState({
    counter: this.state.counter + 1
  });
  this.setState({
    counter: this.state.counter + 1
  });
  this.setState({
    counter: this.state.counter + 1
  });
}

相当于

const state = { counter: 1 };
const newState = Object.assign(
  state,
  { counter: state.counter + 1 },
  { counter: state.counter + 1 },
  { counter: state.counter + 1 },
  { counter: state.counter + 1 },
  { counter: state.counter + 1 },
  { counter: state.counter + 1 }
);
console.log(state); // {counter: 2}
console.log(newState); // {counter: 2}

后调用的 setState() 将覆盖同一周期内先调用 setState 的值,因此商品数仅增加一次

如果本次更新依赖于上一次的更新setState(updater, callback?)需要传入一个函数updater

this.setState((preState, props) => {
  return {
        counter: preState.counter + 1
  };
});

Updater函数

(state, props) => stateChange

Updater函数中接受的stateprops都是最新的值,都是组件中stateprops的引用,返回值会与state进行浅层合并

相关文章

  • react拓展

    setState() setState更新状态的2种方式 对象式的setState 函数式的setState 对象...

  • setState()状态更新函数

    理解setState的关键 setState不会立刻改变React组件中state的值; setState通过引发...

  • 08react基础-react原理

    setState()更新数据 setState()更新数据是异步的 注意:使用该语法,后面的setState不要依...

  • 『react』setState()特性

    一.setState()更新数据 由于setState()更新数据是异步的,所以后面的setState()不要依赖...

  • setState相关

    - setState相关 setState是同步执行的,但是state不一定同步更新 多次执行setState,...

  • react 中的 API

    设置状态:setState setState(object nextState[,function callbac...

  • RN 优化之一

    大组件使用setState ,分离成很小的模块。各用各的setState 把setState 的范围使用到最少。

  • React初探(二)

    探索state和setState 关于state和setState有以下几点注意: 1.调用setState方法来...

  • setState补充

    RN中setState 设置状态 setState(object nextState[,functioncallb...

  • ReactNative:踩过的那些坑

    1.this.setState is not a function 问题分析 this.setState is n...

网友评论

      本文标题:setState

      本文链接:https://www.haomeiwen.com/subject/vshjpktx.html