React 新版官方文档 (二) useState 用法详解

news2024/11/27 15:49:19

在这里插入图片描述

背景

本文默认读者对 useState 有最为基本的了解,比如知道他的写法应当是怎样的,下面着重介绍部分重要的、在开发过程中会踩的坑和一些特性,最后动手实现一个最基本的 useState 代码

useState

⭐️ 注意事项:

  1. 状态只在下次更新时异步变化,如果在设置状态后立即读取值还是老状态的

  2. 如果提供的新状态与当前状态相同 (使用 Object.is 比较),将跳过重新渲染组件以及子组件

  3. React 是批量合并更新 state 的。多个状态更新操作会被放入一个队列中,然后在适当的时机进行合并和批量处理。这可以防止在单个事件期间多次重新渲染,一定会按照顺序。在极少数情况下,需要强制 React 提前更新界面,例如访问 DOM,可以使用 flushSync。
    🌰 例子:

  4. 设置状态后立即读取状态

  5. 使用 setState 并不会改变已执行代码的当前状态 只会影响从下一次渲染开始返回的内容,想获取到变化后的值,可以选用 useEffect
    function handleClick() {
    setName(‘Robin’);
    console.log(name); // Still “Taylor”!
    }

  6. 基于上一次状态更新值
    注意 setState 特性
    function handleClick() {
    // ❌
    setAge(age + 1); // setAge(42 + 1)
    setAge(age + 1); // setAge(42 + 1)
    setAge(age + 1); // setAge(42 + 1)

    // ✅
    setAge(a => a + 1); // setAge(42 => 43)
    setAge(a => a + 1); // setAge(43 => 44)
    setAge(a => a + 1); // setAge(44 => 45)
    }

  7. 更新状态中的对象和数组
    应该替换它而不是修改它
    React 中状态应该是只读的
    // 🚩 Don’t mutate an object in state like this:
    form.firstName = ‘Taylor’;
    // ✅ Replace state with a new object
    setForm({
    …form,
    firstName: ‘Taylor’
    });

  8. 避免重新创建初始状态
    createInitialTodos 有效执行只有组件挂载时一次,但在之后组件历次re-render时都会被执行,这就造成了资源浪费 只需要传递初始化函数声明就行
    function TodoList() { // ❌
    const [todos, setTodos] = useState(createInitialTodos());
    // …
    function TodoList() { // ✅
    const [todos, setTodos] = useState(createInitialTodos);
    // …
    其他问题:https://react.dev/reference/react/useState#troubleshooting

动手实现一个 useState

// 存储状态的数组
let state = []
// 存储更改状态方法的数组
let setters = []
// 用来记录状态和更改状态方法对应关系的下标
let stateIndex = 0

function createSetter(index) {
  return function (newState) {
    state[index] = newState
    render()
  }
}

function useState(initialState) {
  state[stateIndex] = state[stateIndex] ? state[stateIndex] : initialState
  // 采用闭包缓存每个state对应的setState
  setters.push(createSetter(stateIndex))
  const value = state[stateIndex]
  const setter = setters[stateIndex]
  // 每创建完一组都要+1,用来作为下一组状态的索引
  stateIndex++
  return [value, setter]
}

// 因为状态更改要刷新视图,因此这里用ReactDom.render方法来模拟更改状态后刷新视图的操作
function render() {
  // 每次调用render都要重置stateIndex,否则对应的索引无限递增将无法正确匹配state和setState之间的关系
  stateIndex = 0
  ReactDom.render(<App />, document.getElementById('root'))
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/742284.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Shiro教程(一):入门概述与基本使用

Shiro 第一章&#xff1a;入门概述 1.1 Shiro是什么 Apache.Shiro是一个功能强大且易于使用的Java安全&#xff08;权限&#xff09;框架。Shiro可以完成&#xff1a;认证、授权、加密、会话管理、与Web集成、缓存等。借助Shiro可以快速轻松地保护任何应用程序——从最小的移…

用于3D渲染和平面设计应该怎么选择显卡?

首先了解快速解决3D渲染本地配置不足&#xff0c;节省硬件成本的方法&#xff1a; 本地电脑资源不足&#xff0c;在不增加额外的硬件成本投入的情况下&#xff0c;想要快速提升渲染速度&#xff0c;可使用渲云云渲染&#xff0c;且可批量渲染&#xff0c;批量出结果&#xff0…

centos7密码忘记恢复方法

首先启动系统看到如下界面&#xff1a; 然后按"e"键&#xff0c;看到下面的界面 然后使用"↓"按键移动光标&#xff0c; 移动到linux16 将上图中红色箭头指向的ro替换成下图中画红线的内容&#xff1a; ro替换成rw init/sysroot/bin/sh。 然后按CTRLX进入…

【ABAP】数据类型(五)「结构体概要」

💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后端的开发语言ABAP,SQL进行任务的完成,对SAP企业管理系统,SAP ABAP开发和数据库具有较…

Spring Cloud | No URLs will be polled as dynamic configuration sources.

添加config.properties文件就行了&#xff0c;内容为空的都可以 加上该文件再次运行

基于STM32设计的简易手机

一、项目介绍 基于STM32设计的简易手机可以作为智能手表的模型进行开发&#xff0c;方便老人和儿童佩戴。项目主要是为了解决老年人或儿童使用智能手表时可能遇到的困难&#xff0c;例如操作困难、功能复杂等问题。 在这个项目中&#xff0c;采用了STM32F103RCT6主控芯片和SI…

Effective Java(第三版)目录

本书的目标是帮助读者更加有效地使用Java编程语言及其基本类库java.lang、java.util和java.io&#xff0c;以及子包java.util.concurrent和java.util.function等。本书也会时不时地讨论到其他的类库。 本书一共包含90个条目&#xff0c;每个条目讨论一条规则。这些规则…

驱动 day8 作业

1.在内核模块中启用定时器&#xff0c;定时1s,让led1 一秒亮、一秒灭 2.基于gpio子系统完成LED灯驱动的注册&#xff0c;应用程序测试 1.mychrdev_timer.c #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/io…

Qt DAY5 Qt制作简易网络聊天室

服务器 widget.h文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QTcpSocket> #include <QVector>//向量&#xff0c;函数类模板 #include <QMessageBox>namespace Ui { class Widget; }class Wid…

STM32+FreeRTOS 使用SystemView监控系统

前言 本文以STM32F407ZET6 FreeRTOS V9.0作为演示&#xff0c;其它的Cortex M芯片同样可以参考此文&#xff0c;其他内核和RTOS理论上也支持&#xff0c;本文暂时不做研究。 所以开始阅读本文前&#xff0c;需要一块能运行FreeRTOS的Cortex M芯片&#xff0c;如果没有移植好…

发一下接口自动化测试框架(python3+requests+excel)

Git&#xff1a; https://github.com/lilinyu861/Interface-Test 环境配置&#xff1a; 开发工具&#xff1a;pycharm2018Excel 开发框架&#xff1a;python3requestsexcel 接口自动化测试框架介绍&#xff1a; 此接口测试框架&#xff0c;首先由用户设计原始的测试用例并为…

webpack笔记二

文章目录 背景拆分环境清除上次构建产物插件&#xff1a;clean-webpack-plugin合并配置文件插件&#xff1a;webpack-merge实时更新和预览效果&#xff1a;webpack-dev-server babel配置参考 背景 webpack笔记一 在前面的学习&#xff0c;完成了webpack的基本配置&#xff0c…

C++教程——const修饰指针、结构体、文件操作

const修饰指针 常量指针 指针常量 const既修饰指针&#xff0c;又修饰常量 指针与数组 结构体 通过指针访问结构体变量中的数据 结构体中const使用场景 文件操作 写文件 读文件 读取数据的方式 二进制读写文件 写文件 读文件

master、origin master和origin/master

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

线程任务分支合并框架

1、原理 2、实用类 &#xff08;1&#xff09; ForkJoinPool 分支合并池 类比> 线程池 &#xff08;2&#xff09; ForkJoinTask ForkJoinTask 类比> FutureTask &#xff08;3&#xff09; RecursiveTask 递归任务&#xff1a;继承后可以实现递归(自己调自己)调用…

从小白到大神之路之学习运维第57天--------shell脚本实例应用3.0--以及————结合“三贱客”之“grep”的相关用法

第三阶段基础 时 间&#xff1a;2023年7月11日 参加人&#xff1a;全班人员 内 容&#xff1a; shell实例 目录 一、循环的基本使用 while随机循环 二、case控制服务的基本应用 1、case的语法格式 2、使用case写脚本&#xff0c;以以下实验为主 例1&#xff1a;控…

vue + Luckysheet 实现在线Excel表格操作

需求千千万&#xff0c;又是难熬的一天&#xff01; 效果图&#xff1a; Luckysheet官网网站&#xff1a;快速上手 | Luckysheet文档 1、引入&#xff08;两种&#xff09; 第一种CDN引入 在项目中的 public ---> index.html 中添加代码&#xff0c;如下&#xff1a; &…

91.qt qml-圆角毛玻璃 高斯模糊

qml中使用毛玻璃,可以通过两个类型GaussianBlur或者FastBlur使用,效果如下所示: 接下来先来介绍FastBlur和GaussianBlur 1.FastBlur介绍 FastBlur提供比GaussianBlur更低的模糊质量,但渲染速度更快。FastBlur效果通过使用源内容缩小和双线性滤波的算法模糊源内容来软化源内…

【免费送书活动第一期】赠送实体图书《深入浅出Java虚拟机》JVM原理与实战

赠送实体图书四本&#xff08;免费赠送&#xff09; 《深入浅出JAVA虚拟机&#xff1a;JVM原理与实战》 内容简介&#xff1a; 本书主要以 Java 虚拟机的基本特性及运行原理为中心&#xff0c;深入浅出地分析 JVM 的组成结构和底层实现&#xff0c;介绍了很多性能调优的方案和…