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

网站优化自己可以做吗百度收录软件

网站优化自己可以做吗,百度收录软件,公众号发票怎么开,政府网站建设集约化是什么意思在类组件中使用setState,在函数式组件中使用hooks的useState。 setstate目录 1. 类组件1.1 react 17版本1.2 react 18版本 2、函数式组件 1. 类组件 1.1 react 17版本 参考内容:第十一篇:setState 到底是同步的,还是异步的&…

在类组件中使用setState,在函数式组件中使用hooks的useState。

setstate目录

  • 1. 类组件
    • 1.1 react 17版本
    • 1.2 react 18版本
  • 2、函数式组件


1. 类组件

1.1 react 17版本

参考内容:第十一篇:setState 到底是同步的,还是异步的?
                  彻底搞懂setState到底是同步还是异步(一)

1、在react可调度范围内的setState是异步的,并且多次setState会合并只执行最后一次,进行批量更新。

  • react合成事件
  • 生命周期
  • 事件处理,如onClick、onChange等。

2、在react可调度范围外的setState是同步的。

  • 宏任务 setTimeout、setInterval
  • 微任务 .then
  • 原生 js 绑定事件 document.addEventListener()

3、setState 并非真正的异步,而是通过设置全局变量 isBatchingUpdates 来判断 setState是先存进队列还是直接更新,如果值为true,则执行异步操作,如果为false,则直接更新。

      isBatchingUpdates 会在 React 可以控制的地方,则为true,比如React生命周期和合成事件中,而在外部 react 无法控制的地方,比如原生事件,具体就是在 addEventListener、setTimeout、setInterval 、.then等事件中,就只能同步。

4、一般认为,做异步设计是为了性能优化,减少渲染次数。React团队的观点是:

  • 保持内部一致性。如果将 state 改为同步更新,那尽管 state 的更新是同步的,但是 props不是。
  • 启用并发更新,完成异步渲染。

5、案例

import React from "react";
export default class App extends React.Component{state = {count: 0}increment = () => {console.log('increment setState前的count', this.state.count)  //0this.setState({count: this.state.count + 1}); //异步console.log('increment setState后的count', this.state.count)   //0}  //最终count变为1triple = () => {console.log('triple setState前的count', this.state.count)   //1this.setState({count: this.state.count + 1});this.setState({count: this.state.count + 1});this.setState({count: this.state.count + 1});//异步,且合并console.log('triple setState后的count', this.state.count)   //1}   //最终count变为 2reduce = () => {setTimeout(() => {console.log('reduce setState前的count', this.state.count)  //2this.setState({count: this.state.count - 1});//同步  count变为 1console.log('reduce setState后的count', this.state.count)   //1},0);}render(){return <div><button onClick={this.increment}>点我增加</button><button onClick={this.triple}>点我增加三倍</button><button onClick={this.reduce}>点我减少</button></div>}
}

接着我把组件挂载到 DOM 上:

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";const rootElement = document.getElementById("root");ReactDOM.render(<React.StrictMode><App /></React.StrictMode>,rootElement
);

此时浏览器里渲染出来的是如下图所示的三个按钮:
在这里插入图片描述此时有个问题,若从左到右依次点击每个按钮,控制台的输出会是什么样的?

在这里插入图片描述

1.2 react 18版本

参考内容:彻底搞懂setState到底是同步还是异步(二)

      React18版本引入了自动批处理功能,批处理是指,当 React 在一个单独的重渲染事件中批量处理多个状态更新以此实现优化性能。如果没有自动批处理的话,我们仅能够在 React 事件处理程序中批量更新。在 React 18 之前,默认情况下 promise、setTimeout、原生应用的事件处理程序以及任何其他事件中的更新都不会被批量处理;但现在,这些更新内容都会被自动批处理。

1、在react18中setTimeout里的setState也是异步的批量处理了,都是setTimeout 中的批处理明显落后外部的批处理
     上面代码在react18中的结果:0 0 1 1 2 2.

2、案例

import React from 'react';
import './App.css';class AppClass extends React.Component {state = {count: 0,};handleClick = () => {this.setState({ count: 1 });console.log('count: ', this.state.count);   //0this.setState({ count: 2 });console.log('count: ', this.state.count);   //0//异步,合并,count的值变为2setTimeout(() => {this.setState({ count: 3 });console.log('count: ', this.state.count);  //2this.setState({ count: 4 });console.log('count: ', this.state.count);   //2}, 0);//异步,合并,count的值变为4};render() {return (<div className='App'><button onClick={this.handleClick}>count = {this.state.count}</button></div>);}
}export default AppClass;

react 18的控制台打印结果:
在这里插入图片描述
react 17的打印结果:

在这里插入图片描述
对比下结果:

  • 前两次的结果相同,都是0,证明这块是跟 v17 中一样的,都是异步
  • 后两次结果不一样,v17中是同步更新的,所以每次setState 后都可以立即获取到更新后的值,但v18 中打印的是两个2 ,说明是异步更新的,只是这个异步更新跟setTimeout 外部的不在一个批中,setTimeout 中的批处理明显落后外部的批处理。

页面会渲染几次? (执行setState会重新渲染页面)

  • react17中在setTimeout外会合并渲染一次,在setTimeout中是同步的,会渲染两次,总共页面会渲染三次。
  • react18中在setTimeout外会合并渲染一次,在setTimeout中式异步的,进行自动批处理,会渲染一次,总共页面会渲染两次。

2、函数式组件

参考内容:彻底搞懂setState到底是同步还是异步(三)

函数式组件中使用hooks的useState。

1、react 17:由于闭包输出的内容全部是count初始值。在setTimeout外部是异步批处理,在setTimeout内部不是批处理,与react 17中的类组件是否批处理一样。

2、react 18:由于闭包输出的内容全部是count初始值。在setTimeout外部是异步批处理,在setTimeout内部也是自动批处理,与react 18中的类组件是否批处理一样。

3、案例
把上述题目改造成hooks的形式:

import { useState } from 'react';
import './App.css';function App() {const [count, setCount] = useState(0);const handle = () => {setCount(1);console.log('count: ', count);  //0setCount(2);console.log('count: ', count);   //0setTimeout(() => {setCount(3);console.log('count: ', count);   //0setCount(4);console.log('count: ', count);   //0}, 0);};return (<><div className='App'><button onClick={handle}>count is {count}</button></div></>);
}export default App;

react 17的执行结果:

在这里插入图片描述
react 18的执行结果:

在这里插入图片描述

输出结果都是0,看似都是在批处理,为了能更清楚的看到 React 的渲染行为,修改下上边的代码,在每次渲染都都打印下当前的 count值,添加如下代码:

useEffect(() => {console.log('render: 此时的count: ', count);});

再次查看输出结果:

在这里插入图片描述
在这里插入图片描述

分析下:

  • 在 React 17 下,render 打印了 3 次,说明组件重新渲染了 3 次,回顾下当时讲解 React 17 的 setState时,setTimeout外是批处理重新渲染一次,setTimeout中是同步渲染,重新渲染两次,能对上。
  • 再来看下 React 18 下,render 打印了 2 次,说明组件重新渲染了 2 次,在对比下前面讲解的 React18 的自动批处理功能,setTimeout外部批处理一次,内部批处理一次,重新渲染两次,也能对上.
  • 那为什么这期间打印的 count 都是 0 呢?

        这是由于js的特性闭包导致的,闭包就是内部函数可以访问外部函数的变量。

        组件App是一个函数,handle 是 App内的函数,这也就形成了一个闭包,所以 handle 函数才能访问到 count 变量的值。

        无论延时多长时间,最终打印的count值一直是旧值,也就是 0。

        要是想要立即用更新后的state,可以使用setState的第二个函数。

http://www.ds6.com.cn/news/47359.html

相关文章:

  • 自己做的网站能上传吗sem营销推广
  • 做网站的一些好处如何自己建个网站
  • 简述主要的电子商务网站有哪些手机如何建立网站
  • 做塑料的网站名字营销推广策略
  • 做网站申请域名大概花费多少河南网站seo推广
  • 网站怎么制作小程序网站域名怎么注册
  • 网站怎么做双语种免费网页模板网站
  • 大连市城乡建设档案馆网站体验营销理论
  • 网站开发公司网站模板网站空间租用
  • 重庆品牌网站建设公司江苏seo哪家好
  • 工业和信息化网站备案系统seo网站推广下载
  • 备案网站内容简介网站内容如何优化
  • 网站怎么在移动端推广廊坊seo整站优化软件
  • 网站建设中页面源码网站模板免费下载
  • 服装网站页面设计厦门seo新站策划
  • 如何设计网站制作方案项目营销推广策划
  • 国内知名网站建设html网页完整代码作业
  • 动漫建模代做网站百度一下百度seo关键词工具
  • 外贸soho做网站如何制作自己的链接
  • 公司网站建设需要资质武汉网络推广有哪些公司
  • 图片 套网站模板下载 迅雷下载 迅雷下载地址mac日本官网入口
  • wordpress文章摘要显示网站seo优化推广
  • 岳阳市住房和城乡建设局网站百度搜索下载app
  • 建设网站实施条件上海网站推广服务公司
  • 网站安全检测可以检测哪些内容风险信息今日头条国际军事新闻
  • 遵义网站建设公司电话多少电商网站网址
  • 建设银行个人网上银行入口seo技术分享博客
  • 广告牌logo设计制作南阳seo
  • 企业网站是否可以做淘宝客免费关键词挖掘工具
  • 金山网站建设费用台州seo快速排名