ReactHooks:渲染与useState

2024-01-11 14:20
文章标签 渲染 usestate reacthooks

本文主要是介绍ReactHooks:渲染与useState,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

渲染和提交

组件显示到屏幕之前,必须被 React 渲染。主要需要经历以下三个步骤:

步骤1: 触发一次渲染

有两种原因会导致组件的渲染:

  • 组件的初次渲染
  • 组件(或其父组件)的状态发生改变而触发重新渲染

当应用启动时,会触发初次渲染。一旦组件被初次渲染,就可以调用 set 函数(useState)更新其状态来触发之后的渲染。更新组件的状态会自动将一次渲染送入队列。

可以把这种情况想象成餐厅客人在第一次下单之后又点了茶、点心和其他东西,每次点单到厨房都相当于触发一次渲染。

步骤2:React 渲染组件

在触发一次渲染后,React 会调用组件来确定在屏幕上显示的内容。

这个过程是递归的,如果更新后的组件会返回某个另外的组件(子组件),React 会继续渲染这个子组件。以此类推,这个过程会持续下去,直到没有更多的嵌套组件并且 React 确切知道哪些东西应该显示到屏幕上为止。

如果更新的组件在树中的位置非常高,默认会渲染更新组件中所有的嵌套组件,这种行为可能会影响性能。

在渲染组件的过程中,React 会将更新后的虚拟 DOM 与旧的虚拟 DOM 进行对比,通过 diff 算法找出需要更新的节点,从而在提交阶段应用最少的必要操作来操作真实 DOM,提交性能。

  • 真实DOM:浏览器在解析HTML文档时,会将每个标签元素抽象成DOM节点,按照标签元素层次分明的结构,将HTML文档构建成一棵DOM树。
  • 虚拟DOM:虚拟DOM本质上是一个js对象,通过对象来表示真实的DOM结构。tag用来描述标签,props用来描述属性,children用来表示嵌套的层级关系。在状态变化时,会重新生成一个新的虚拟DOM,通过将新旧两个虚拟DOM树进行比较,只将差异的节点应用在真实DOM树上。

步骤3:React 把更新提交到 DOM 上

在渲染组件之后,React 仅在渲染之间存在差异时才会更改 DOM 节点。在渲染完成并且 React 更新 DOM 之后,浏览器就会重新绘制屏幕。

state

想要页面对输入做出反应,需要设置 state 触发重新渲染。

state 如同一张快照,React 在调用(渲染)组件时,组件会在其 JSX 中返回一张包含一整套新的 props 和事件处理函数的 UI 快照,其中所有的值都是根据这一次渲染中 state 中的值计算出来的。

一个 state 变量的值永远不会在一次渲染的内部发生变化, 即使其事件处理函数的代码是异步的。

const [count, setCount] = useState(0);const onClick = () => {setCount(count + 1);setCount(count + 1);setTimeout(() => {alert(count);}, 3000);
}
// 最终结果:点击按钮之后,页面触发重新渲染 count会变为 1,3秒后 alert显示内容为 0

在这次渲染的过程中,state 变量 count 的值为 0,使用替代法可以将事件处理函数变成下面这样:

setCount(0 + 1);
setCount(0 + 1);
setTimeout(() => { alert(0) }, 3000);

除此之外,state 变量还有一个重要的特性:批处理

React 会将一系列的 state 更新加入队列,等到事件处理函数中的所有代码都运行之后再遍历队列,进行 state 更新。这使得可以一次更新多个 state 变量而不会触发太多次的重新渲染。

const [count, setCount] = useState(0);

setCount(count + 1);
setCount(count + 1);			// 1
// setCount(0 + 1);
// setCount(0 + 1);
setCount(count + 1);
setCount(count + 5);			// 5
// setCount(0 + 1);
// setCount(0 + 5);
setCount(count => count + 1);
setCount(count => count + 1);	// 2
// setCount(0 => 0 + 1);
// setCount(1 => 1 + 1);
setCount(count => count + 1);
setCount(count + 5);			// 5
// setCount(0 => 0 + 1);
// setCount(0 + 5);
setCount(count + 1);
setCount(count => count + 5);	// 6
// setCount(0 + 1);
// setCount(1 => 1 + 5);

state 更新

state 中可以存储任意类型的 js 值。对于基础数据类型,可以通过直接替换它们的值来触发一次渲染。对于对象或数组,则需要创建一个新的对象或数组并将其传递给 state 的设置函数。

对象:使用 … 展开语法进行复制

const [person, setPerson] = useState({name: 'Niki de Saint Phalle',artwork: {title: 'Blue Nana',city: 'Hamburg',image: 'https://i.imgur.com/Sd1AgUOm.jpg',}
});setPerson({...person, 	// 复制其它字段的数据 artwork: { 	// 替换 artwork 字段 ...person.artwork, 	// 复制之前 person.artwork 中的数据city: 'New Delhi' 	// 但是将 city 的值替换为 New Delhi!}
});

数组

const [ products, setProducts ] = useState([{ name: 'Baklava', count: 1},{ name: 'Cheese', count: 5},
])

新增:… 数组展开

setProducts([ ...products, { name: 'Spaghetti', count: 2}
]);	 // 可以加在开头或末尾

插入中间:slice

setProducts([...products.slice(0, 1),{ name: 'Spaghetti', count: 2},...products.slice(1),
])

删除:filter

setProducts(products.filter(p => p.count <= 1);
)

更新:map

setProducts(products.map(p => {if (p.name === 'Cheese'){return { ...p, count: p.count + 1};}return p;})
)

排序:先拷贝一份

const newProducts = [ ...products];
newProducts.sort((a, b) => b.count - a.count);
setProducts(newProducts);

这篇关于ReactHooks:渲染与useState的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/594660

相关文章

OpenGL ES 2.0渲染管线

http://codingnow.cn/opengles/1504.html Opengl es 2.0实现了可编程的图形管线,比起1.x的固定管线要复杂和灵活很多,由两部分规范组成:Opengl es 2.0 API规范和Opengl es着色语言规范。下图是Opengl es 2.0渲染管线,阴影部分是opengl es 2.0的可编程阶段。   1. 顶点着色器(Vert

【鸿蒙HarmonyOS NEXT】调用后台接口及List组件渲染

【鸿蒙HarmonyOS NEXT】调用后台接口及List组件渲染 一、环境说明二、调用后台接口及List组件渲染三、总结 一、环境说明 DevEco Studio 版本: API版本:以12为主 二、调用后台接口及List组件渲染 后台接口及返回数据分析 JSON数据格式如下: {"code": 0,"data": {"total": 6,"pageSize"

【爬虫渲染神器】selenium 和pyppeteer 的动态渲染ajax反爬虫

许多网页是动态加载的网页,其中不乏使用了ajax异步技术,那么我们有没有一种渲染工具,直接省略分析过程,模拟浏览器渲染的操作呢,获取到我们想要的内容。当然有,下面我们介绍两种渲染工具的实战使用。 目标网站: http://www.porters.vip/verify/sign/ 点击参看详情页的里面内容。 前一篇文章,我们介绍了,js逆向分析两种方法JS逆向–签名验证反爬虫】sign签名验证

如何将 Redshift Cryptomatte AOV 与 teamrender 结合使用,成都渲染101云渲染

这篇文章将讨论在 Cinema 4D 中将 cryptomatte AOV 与 teamrender 结合使用时常见的问题和解决方案。在 Cinema 4D 中使用 AOV 时,用户希望它们的工作方式与其他 AOV 完全相同。但事实并非如此,尤其是与 teamrender 结合使用时。  在 Cinema 4D 中,使用AOV 面板中的Multi-pass和Direct复选框之间的区别非常重要。

vue中跳转当前页无法重渲染且报错问题

1、解决报错: // router/index.jsimport Vue from 'vue'import VueRouter from 'vue-router'Vue.use(VueRouter)// 解决报错👇const routerPush = VueRouter.prototype.pushVueRouter.prototype.push = function push(l

HarmonyOS开发实战( Beta5版)高负载组件的渲染实践规范

简介 在应用开发中,有的页面需要在列表中加载大量的数据,就会导致组件数量较多或者嵌套层级较深,从而引起组件负载加重,绘制耗时增长。虽然可以通过组件复用避免组件重复创建,但是如果每个列表项中包含的组件较多,在转场或者列表滑动的时候列表项就会一次性加载大量的数据,可能引起卡顿掉帧等性能问题。 转场场景 由于业务需求,从当前页面进入一个新页面时,会有转场动画播放,并且在动画首帧中加载新页面所需要的

浏览器输入url到渲染完成经历了那些内容

问: 浏览器输入url到渲染完成经历了那些内容 回答: 从浏览器输入 URL 到页面渲染完成的过程涉及多个步骤,每个步骤都涉及特定的网络和计算机科学技术。以下是这一过程的基本流程: URL 解析: 用户在浏览器地址栏输入 URL(统一资源定位符)。浏览器解析 URL,分解成协议(如 HTTP/HTTPS)、域名、路径、查询参数等。 DNS 查询: 浏览器检查本地缓存是否有该域名的 IP

自定义渲染组件及材质 / 引擎源码 / Dashboard

B站视频: Cocos Creator 3D 官方中文教程——《快上车3D》案例添加链接描述 (请点击跳转) cocos creator 1.x shader 没有经过包装,可以直接定义shader,替换 sprite 原来的 shader,可以参考之前博客; cocos creator 2.x 引入了材质系统,使用 shader 必须通过材质,这里介绍下如何使用自定义 shade

cocos2dx与OpenGL渲染知识

1 顶点和片段介绍 2 why不同纹理会需要重新渲染 纹理优化--------- 3 通俗易懂的 OpenGL ES 3.0 和2.0区别 –参考文档: https://blog.csdn.net/u013654125/article/details/79698469 ~ https://blog.csdn.net/sun___shine/article/details/48313749 Coc

什么叫3d建模渲染?与云渲染农场关系

3D建模渲染行业是一个涉及多个行业和领域的技术过程,它不仅仅是一个特点行业的产物,而是广泛应用于产品设计、工业设计、环境设计、动画、游戏建模和影视CG等多个领域。那么3D建模渲染又与云渲染农场有什么关系呢,一起来简单看看吧。 什么叫3d建模渲染? 这个过程可以分为两个主要阶段:建模和渲染。 3D建模:是创建三维对象或场景的过程。这可以是设计一个新的产品的外观和结构,也可以是构建一个虚