当前位置: 首页 > news >正文

网站affiliate怎么做?百度浏览器手机版

网站affiliate怎么做?,百度浏览器手机版,头条淘宝联盟网站推广怎么做,网站开发如何引用函数先来思考一个老生常谈的问题,setState是同步还是异步? 再深入思考一下,useState是同步还是异步呢? 我们来写几个 demo 试验一下。 先看 useState 同步和异步情况下,连续执行两个 useState 示例 function Component() {const…

先来思考一个老生常谈的问题,setState是同步还是异步?

再深入思考一下,useState是同步还是异步呢?

我们来写几个 demo 试验一下。

先看 useState

同步和异步情况下,连续执行两个 useState 示例

function Component() {const [a, setA] = useState(1)const [b, setB] = useState('b')console.log('render')function handleClickWithPromise() {Promise.resolve().then(() => {setA((a) => a + 1)setB('bb')})}function handleClickWithoutPromise() {setA((a) => a + 1)setB('bb')}return (<Fragment><button onClick={handleClickWithPromise}>{a}-{b} 异步执行      </button><button onClick={handleClickWithoutPromise}>{a}-{b} 同步执行      </button></Fragment>)
}

结论:

  • 当点击同步执行按钮时,只重新 render 了一次
  • 当点击异步执行按钮时,render 了两次

同步和异步情况下,连续执行两次同一个 useState 示例

function Component() {const [a, setA] = useState(1)console.log('a', a)function handleClickWithPromise() {Promise.resolve().then(() => {setA((a) => a + 1)setA((a) => a + 1)})}function handleClickWithoutPromise() {setA((a) => a + 1)setA((a) => a + 1)}return (<Fragment><button onClick={handleClickWithPromise}>{a} 异步执行</button><button onClick={handleClickWithoutPromise}>{a} 同步执行</button></Fragment>)
}
  • 当点击同步执行按钮时,两次 setA 都执行,但合并 render 了一次,打印 3
  • 当点击异步执行按钮时,两次 setA 各自 render 一次,分别打印 2,3

参考 前端进阶面试题详细解答

再看 setState

同步和异步情况下,连续执行两个 setState 示例

class Component extends React.Component {constructor(props) {super(props)this.state = {a: 1,b: 'b',}}handleClickWithPromise = () => {Promise.resolve().then(() => {this.setState({...this.state, a: 'aa'})this.setState({...this.state, b: 'bb'})})}handleClickWithoutPromise = () => {this.setState({...this.state, a: 'aa'})this.setState({...this.state, b: 'bb'})}render() {console.log('render')return (<Fragment><button onClick={this.handleClickWithPromise}>异步执行</button><button onClick={this.handleClickWithoutPromise}>同步执行</button></Fragment>)}
}
  • 当点击同步执行按钮时,只重新 render 了一次
  • 当点击异步执行按钮时,render 了两次

跟useState的结果一样

同步和异步情况下,连续执行两次同一个 setState 示例

class Component extends React.Component {constructor(props) {super(props)this.state = {a: 1,}}handleClickWithPromise = () => {Promise.resolve().then(() => {this.setState({a: this.state.a + 1})this.setState({a: this.state.a + 1})})}handleClickWithoutPromise = () => {this.setState({a: this.state.a + 1})this.setState({a: this.state.a + 1})}render() {console.log('a', this.state.a)return (<Fragment><button onClick={this.handleClickWithPromise}>异步执行</button><button onClick={this.handleClickWithoutPromise}>同步执行</button></Fragment>)}
}
  • 当点击同步执行按钮时,两次 setState 合并,只执行了最后一次,打印 2
  • 当点击异步执行按钮时,两次 setState 各自 render 一次,分别打印 2,3

这里跟useState不同,同步执行时useState也会对state进行逐个处理,而setState则只会处理最后一次

为什么会有同步执行和异步执行结果不同呢?

这里就涉及到 react 的 batchUpdate 机制,合并更新。

  • 首先,为什么需要合并更新呢?

如果没有合并更新,在每次执行 useState 的时候,组件都要重新 render 一次,会造成无效渲染,浪费时间(因为最后一次渲染会覆盖掉前面所有的渲染效果)。
所以 react 会把一些可以一起更新的 useState/setState 放在一起,进行合并更新。

  • 怎么进行合并更新

这里 react 用到了事务机制。

React 中的 Batch Update 是通过「Transaction」实现的。在 React 源码关于 Transaction 的部分,用一大段文字及一幅字符画解释了 Transaction 的作用:

*                       wrappers (injected at creation time)
*                                      +        +
*                                      |        |
*                    +-----------------|--------|--------------+
*                    |                 v        |              |
*                    |      +---------------+   |              |
*                    |   +--|    wrapper1   |---|----+         |
*                    |   |  +---------------+   v    |         |
*                    |   |          +-------------+  |         |
*                    |   |     +----|   wrapper2  |--------+   |
*                    |   |     |    +-------------+  |     |   |
*                    |   |     |                     |     |   |
*                    |   v     v                     v     v   | wrapper
*                    | +---+ +---+   +---------+   +---+ +---+ | invariants
* perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained
* +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
*                    | |   | |   |   |         |   |   | |   | |
*                    | |   | |   |   |         |   |   | |   | |
*                    | |   | |   |   |         |   |   | |   | |
*                    | +---+ +---+   +---------+   +---+ +---+ |
*                    |  initialize                    close    |
*                    +-----------------------------------------+

用大白话说就是在实际的 useState/setState 前后各加了段逻辑给包了起来。只要是在同一个事务中的 setState 会进行合并(注意,useState不会进行state的合并)处理。

  • 为什么 setTimeout 不能进行事务操作

由于 react 的事件委托机制,调用 onClick 执行的事件,是处于 react 的控制范围的。

而 setTimeout 已经超出了 react 的控制范围,react 无法对 setTimeout 的代码前后加上事务逻辑(除非 react 重写 setTimeout)。

所以当遇到 setTimeout/setInterval/Promise.then(fn)/fetch 回调/xhr 网络回调时,react 都是无法控制的。

相关react 源码如下:

if (executionContext === NoContext) {// Flush the synchronous work now, unless we're already working or inside// a batch. This is intentionally inside scheduleUpdateOnFiber instead of// scheduleCallbackForFiber to preserve the ability to schedule a callback// without immediately flushing it. We only do this for user-initiated// updates, to preserve historical behavior of legacy mode.flushSyncCallbackQueue()
}

executionContext 代表了目前 react 所处的阶段,而 NoContext 你可以理解为是 react 已经没活干了的状态。而 flushSyncCallbackQueue 里面就会去同步调用我们的 this.setState ,也就是说会同步更新我们的 state 。所以,我们知道了,当 executionContext 为 NoContext 的时候,我们的 setState 就是同步的

总结

我们来总结一下上述实验的结果:

  1. 在正常的react的事件流里(如onClick等)
  • setState和useState是异步执行的(不会立即更新state的结果)
  • 多次执行setState和useState,只会调用一次重新渲染render
  • 不同的是,setState会进行state的合并,而useState则不会
  1. 在setTimeout,Promise.then等异步事件中
  • setState和useState是同步执行的(立即更新state的结果)
  • 多次执行setState和useState,每一次的执行setState和useState,都会调用一次render

是不是感觉有点绕,自己写一下代码体验一下就好了~

http://www.hkea.cn/news/765201/

相关文章:

  • 手机网站开发 pdfseo搜索引擎优化工作内容
  • 上海中小网站建设洛阳seo博客
  • 南宁网站建设公司哪家专业搜索引擎优化包括
  • 新疆住房与建设厅网站新产品推广方式有哪些
  • 做网站站怎么赚钱网络营销模式有哪些?
  • 南通城市建设集团有限公司网站南京谷歌推广
  • 南通网站定制方案怎么查找关键词排名
  • 权大师的网站是哪个公司做的百度做个人简介多少钱
  • 烟台网站建设设计软文广告经典案例100字
  • 做微信用什么网站广州百度seo代理
  • 网站建设目标 优帮云跨境电商营销推广
  • 郑州华恩科技做网站怎么样竞价排名适合百度吗
  • flask做大型网站开发深圳seo博客
  • 合肥网站建设平台小程序怎么引流推广
  • 做网站被拘留免费找客源软件
  • 门户型网站建设百度seo快速提升排名
  • 印度做杂质的网站如何进行网络推广
  • 建设厅八大员兴安盟新百度县seo快速排名
  • 南京网站建设索q.479185700小说排行榜百度
  • 幼儿做爰网站seo工程师是什么职业
  • 申请空间 建立网站吗西安百度推广运营
  • 做花馍网站百度联盟
  • 沈阳建设企业网站google浏览器官网
  • 毕业论文 网站开发营销qq下载
  • 建网站要多长时间外贸网站优化
  • 苹果网站做的好的点电脑培训网上免费课程
  • 做网站开源互联网优化是什么意思
  • 模仿做网站b站上海热点新闻
  • phpcmsv9网站地图地推的60种方法
  • 湖南手机版建站系统哪个好百度网盘app怎么打开链接