React知识点汇总(基础使用2)

【重点】setState

  • 不可变值
  • 可能是异步更新
  • 可能会被合并

state 要在构造函数中定义

  • 函数组件(后面会讲),默认没有 state
  • state 要在构造函数中定义

不能直接修改 state ,使用 不可变值

  • 不能直接修改 state,需要使用setState。也不能提前修改state再使用setState,在setState中什么使用需要state再进行修改。
  • 简单例子:修改state中的值类型不能直接修改 state(原因:shouldComponentUpdate中具体阐述)

修改state中的引用类型

  • 原则:在setState中使用的方法都不能改变state中的原数组/对象(比如数组的push pop splice都不能使用),或者在setState前先拷贝数组/对象来进行操作。
  • 【数组】state中存放 数组时,需要注意不能直接对 this.state.list 进行 push pop splice 等会直接改变原数组(state中数据)的操作,这样违反不可变值。需要做复杂操作时,可先拷贝出来再进行操作。修改state中存放的数组ES6 filter-数组过滤方法
  • 【对象】巧用assign方法将state中对象放在参数2,则可不改变state中原对象。修改state中存放的对象

setState 可能是异步/同步更新

  • 能命中batchUpdate机制的入口(即:react可以“管理”的入口)中使用 setState 是异步JSX中、合成事件中
  • 不能命中batchUpdate机制的入口(即:react“管不到”的入口)中使用 setState 是同步setTimeout setInterval等、自定义的DOM事件(注意搭配componentWillUnmount()中使用removeEventListener()解绑事件,react合成事件统一绑定在document上,就不需要频繁解绑了)

JSX 中使用 setState 是异步

  • 直接在JSX中使用 setState 是异步的:setState 异步更新的例子
  • 但是setState的参数2(回调函数)中可获取到最新state

JSX合成事件 中使用 setState 是异步

  • 此处无例子
  • 注意:onclick是DOM事件,通过addEventListener绑定的click事件是“自定义的 DOM 事件”,JSX中的onClick是 合成事件

原生DOM事件 中使用 setState 是同步

  • 自定义的 DOM 事件中 setState 是同步的(即原生DOM事件中是同步的,只要html中能正常跑起来的绑定方法就是原生DOM事件):自己定义的 DOM 事件中 setState 是同步的在body上绑定自定义的click事件,在该DOM事件中setState 是同步的
    • 注意:“自定义的 DOM 事件”的概念,onclick是DOM事件,通过addEventListener绑定的click事件是“自定义的 DOM 事件”,JSX中的onClick是 合成事件

setTimeout 中使用 setState 是同步

setTimeout 中 setState 是同步的:setTimeout 中 setState 是同步的

setState异步更新前合并/不合并

setState中传入 对象 会被合并

state 异步更新时,setState中传入对象,会被合并,执行结果只一次,点击一次“累加”按钮的执行结果是 +1传入对象,更新前会被合并,执行结果只一次一样用点击按钮累加数字作为例子,点击事件的事件函数increase中设置3次setState,由于这里是异步的setState,所以点击按钮时,系统会发现setState3次都是一样的修改,最后会被合并为1次(即每次点击都只+1不会+3 )

setState中传入 函数 不合并

  • state 异步更新时,setState中传入函数,不会被合并。点击一次“累加”按钮的执行结果是 +3传入函数,不会被合并。点击一次“累加”按钮的执行结果是 +3
    • 函数是无法合并的,所以三个函数都会生效

补充:setState()的两个参数

  • 注意:setState中推荐传入函数
  • setState()的参数1(回调函数)可以接受两个参数:prevState, props(),第一个参数是原始state,等同于this.state,第二个参数是父组件传递的属性。(参考)
  • setState()的参数2(回调函数)内可获取state的最新值,在这个函数内可解决由于setState是异步的,有些事件我们需要等setState更新完才触发的问题(参考)

组件生命周期


,