政务公开网站建设意义,wordpress底端小工具,网站UI怎么做,国内知名企业网站setState 是 react 中更新 UI 的唯一方法#xff0c;其内部实现原理如下#xff1a;
调用 setState 函数时#xff0c;React 将传入的参数对象加入到组件的更新队列中。React 会调度一次更新#xff08;reconciliation#xff09;#xff0c;在调度过程中#xff0c;Re…setState 是 react 中更新 UI 的唯一方法其内部实现原理如下
调用 setState 函数时React 将传入的参数对象加入到组件的更新队列中。React 会调度一次更新reconciliation在调度过程中React 会根据组件的 state 和 props 来计算出组件的新的状态并比较新旧的状态决定是否需要重新渲染组件。
this.setState([particalState], [callback])中
particalState 是一个对象支持部分修改 state,只更新当前要修改的属性其余的保持不变。callback 是可选的函数在 setState 更新完成之后执行。类似于 vue 中的 nextTick 机制。 发生在 componetDidUpdate 生命周期之后DOM 更新完成之后。componetDidUpdate 会在任何 state 更新之后调用不管是否是 setState 引起的。这里的回调函数只会在特定的 state 变化后出发还要主动调用。即使我们使用了 shouldComponentUpdate返回 false 来组织组件更新 componentDidUpdate 不更新了回调函数依然会执行。
import { Component } from react;class ClassComp extends Component {state {x: 10,y: 20,z: 0,};handleAdd () {// this是指向当前组件的实例箭头函数式没有自己的thisthis.setState({x: this.state.x 1,},() {console.log(this.state.x, xxxxxxxxxxxxx);});};shouldComponentUpdate() {return false;}componentDidUpdate() {console.log(componentDidUpdate class component);}render() {console.log(render class component);const { x, y, z } this.state;return (divClass Componentpx: {x}, y: {y} z:{z}br /button onClick{this.handleAdd}add/button/p/div);}
}
export default ClassComp;setState 的同步与异步 r18 中setState 在任何地方都是异步的,包括合成事件周期函数定时器。。。 r18 中有一套更新队列的机制,[updater]来处理的基于异步操作实现状态的批处理 好处 异步的目的是为了性能优化在多个 setState 调用时可以合并成一个 state 更新 异步的目的是为了防止 setState 调用过于频繁造成性能问题 在 r18 之前。我们只在 react 的合成事件和生命周期函数中调用 setState 做批量更新默认情况下不会对原生事件,promise,setTimeout,requestAnimationFrame 等异步操作做批量更新。
r16 中的执行效果
r18 中的执行效果 需求
点击一个按钮让数字 x 加一结果为 30
import { Component } from react;
class ClassComp extends Component {state {x: 10,y: 20,z: 0,};handleAdd () {for (let i 0; i 20; i) {this.setState(x:this.state.x1);}console.log(this.state.x);};render() {console.log(render class component);const { x, y, z } this.state;return (divClass Componentpx: {x}, y: {y} z:{z}br /button onClick{this.handleAdd}add/button/p/div);}
}
export default ClassComp;可以发现打印结果为 1, 不是 30,改造代码引入 flushSync 写法 1
import { Component } from react;
import { flushSync } from react-dom;handleAdd () {for (let i 0; i 20; i) {flushSync(() {this.setState(x:this.state.x1);}}console.log(this.state.x);};export default ClassComp;写法 2
import { Component } from react;
import { flushSync } from react-dom;handleAdd () {for (let i 0; i 20; i) {this.setState(x:this.state.x1);flushSync()}console.log(this.state.x);};export default ClassComp;可以看到 render 执行了 20 次但是打印结果为 30,如果只让 render 执行一次打印结果为 30,需要改造代码
import { Component } from react;
class ClassComp extends Component {state {x: 10,y: 20,z: 0,};handleAdd () {for (let i 0; i 20; i) {this.setState((prev) {return { x: prev.x 1 };});}console.log(this.state.x);};render() {console.log(render class component);const { x, y, z } this.state;return (divClass Componentpx: {x}, y: {y} z:{z}br /button onClick{this.handleAdd}add/button/p/div);}
}
export default ClassComp;