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

【React】useState:状态更新规则详解

文章目录

    • 一、基本用法
    • 二、直接修改状态 vs 使用 `setState` 更新状态
    • 三、对象状态的更新
    • 四、深层次对象的更新
    • 五、函数式更新
    • 六、优化性能的建议

在 React 中,useState 是一个非常重要的 Hook,用于在函数组件中添加状态管理功能。正确理解和使用 useState 更新状态的规则,对于构建高效和可维护的 React 应用至关重要。本文将通过详细的解释和代码示例,帮助您深入理解 useState 的状态更新规则。

一、基本用法

useState 的基本用法非常简单。它返回一个状态变量和一个更新该状态的函数:

import { useState } from 'react';function App() {const [count, setCount] = useState(0);const handleClick = () => {setCount(count + 1);};return (<div><button onClick={handleClick}>{count}</button></div>);
}export default App;

在这个例子中,useState(0) 初始化了一个状态变量 count,初始值为 0,setCount 是用于更新 count 的函数。每次点击按钮,count 的值都会加 1,并触发组件重新渲染。

二、直接修改状态 vs 使用 setState 更新状态

在使用 useState 时,直接修改状态变量不会触发组件重新渲染。只有通过 setState 函数更新状态,React 才会知道状态发生了变化,并触发重新渲染:

import { useState } from 'react';function App() {const [count, setCount] = useState(0);const handleClick = () => {// 直接修改不会触发视图更新// count++;// console.log(count);// 正确写法:使用 setCountsetCount(count + 1);};return (<div><button onClick={handleClick}>{count}</button></div>);
}export default App;

在上述代码中,如果我们直接修改 count 的值,如 count++,视图不会更新,因为 React 不知道状态已经改变。正确的做法是使用 setCount 更新状态,这样 React 才能检测到状态变化并重新渲染组件。

三、对象状态的更新

使用 useState 管理对象状态时,需要注意不要直接修改对象,而是通过创建新对象来更新状态。直接修改对象属性不会触发组件重新渲染:

import { useState } from 'react';function App() {const [form, setForm] = useState({ name: 'jack' });const changeForm = () => {// 错误写法:直接修改对象// form.name = 'john';// 正确写法:创建一个新对象setForm({...form,name: 'john'});};return (<div><button onClick={changeForm}>修改form {form.name}</button></div>);
}export default App;

在这个例子中,如果我们直接修改 form.name 的值,如 form.name = 'john',视图不会更新。正确的做法是通过 setForm 创建一个新对象来更新状态。

四、深层次对象的更新

当状态是一个嵌套的深层次对象时,更新状态需要更加谨慎。确保每个层次的对象都创建一个新的副本,才能保证 React 检测到状态变化并重新渲染组件:

import { useState } from 'react';function App() {const [user, setUser] = useState({name: 'jack',address: {city: 'New York',country: 'USA'}});const changeCity = () => {setUser({...user,address: {...user.address,city: 'Los Angeles'}});};return (<div><button onClick={changeCity}>修改城市 {user.address.city}</button></div>);
}export default App;

在这个例子中,我们更新了嵌套对象 addresscity 属性。通过创建 useraddress 的新副本,React 能够检测到状态变化并重新渲染组件。

五、函数式更新

当新状态依赖于之前的状态时,使用函数式更新可以避免潜在的竞态条件。函数式更新接收一个函数,该函数的参数是之前的状态,返回新的状态值:

import { useState } from 'react';function App() {const [count, setCount] = useState(0);const handleClick = () => {setCount(prevCount => prevCount + 1);};return (<div><button onClick={handleClick}>{count}</button></div>);
}export default App;

在这个例子中,setCount 接收一个函数 prevCount => prevCount + 1。这个函数的参数 prevCount 是之前的状态值,返回新的状态值。这种方式可以确保状态更新的正确性,尤其是在多个状态更新操作可能同时发生时。

六、优化性能的建议

  1. 避免不必要的状态更新

    确保只有在状态确实发生变化时才调用 setState,以避免不必要的重新渲染。

    const handleClick = () => {if (count !== newCount) {setCount(newCount);}
    };
    
  2. 使用 React.memo 进行性能优化

    对于函数组件,可以使用 React.memo 进行性能优化,使组件在相同的 props 下不重新渲染。

    const MyComponent = React.memo(({ value }) => {return <div>{value}</div>;
    });
    
  3. 避免在 render 方法中定义函数

    render 方法中定义函数会导致每次渲染时都创建新的函数实例,影响性能。将函数定义在组件外或使用 useCallback Hook 缓存函数。

    import { useCallback } from 'react';const handleClick = useCallback(() => {setCount(prevCount => prevCount + 1);
    }, []);
    

.


在这里插入图片描述

相关文章:

【React】useState:状态更新规则详解

文章目录 一、基本用法二、直接修改状态 vs 使用 setState 更新状态三、对象状态的更新四、深层次对象的更新五、函数式更新六、优化性能的建议 在 React 中&#xff0c;useState 是一个非常重要的 Hook&#xff0c;用于在函数组件中添加状态管理功能。正确理解和使用 useState…...

C#中的异步编程:Task、Await 和 Async

public async void DoSth() {await Task.Run(() > {//...DoSth...}); } ①函数的返回类型前加上&#xff1a; async ②函数内加上&#xff1a; await Task.Run(() > { }); ③在上面{ ... } 内添加要处理的程序代码&#xff0c; 这样运行到 DoSth() 函数就…...

SSRF-labs-master靶场

目录 file_get_content.php sql_connect.php download.php dns-spoofing.php dns_rebinding.php 访问链接 http://127.0.0.1/SSRF/# file_get_content.php 在编程语言中&#xff0c;有一些函数可以获取本地保存文件的内容。这些功能可能能够从远程URL以及本地文件 如果没…...

HBuilder X中配置vue-cli项目和UI库

目录 一.前端项目结构 二.在HBuilder X中搭建vue-cli项目 1. 安装node.js前端环境 2. HBuilder X创建一个vue-cli项目 3. vue-cli项目结构 4. 如何运行前端项目 5. 创建组件 6. 组件路由(页面跳转) 6.1 创建router目录 6.2 使用路由 6.3 在main.js中配置路由 6.4 路…...

如何用PostMan按照规律进行循环访问接口

①设置动态变量 步骤一: 设置环境变量 1. 创建环境变量集合 在 Postman 左上角选择 "环境"&#xff0c;然后点击 "添加" 来创建一个新的环境变量集合。给它起一个名称&#xff0c;比如 "uploadDemo". 2. 添加初始变量 在新创建的环境变量集…...

稳态准直太阳光模拟器仪器光伏电池组件IV测试

太阳能模拟器电池IV测试仪、单体测试仪&#xff0c;配备匹配标准的AAA Class稳态太阳能模拟器及相关测试附件&#xff0c;可对太阳能电池片的IV性能进行测量、分级分选等&#xff1b; 介绍 AAA class太阳光模拟器整合完整的IV测量系统&#xff0c;针对各种太阳能电池的性能&a…...

vue3 reactive原理(二)-代理Set和Map及ref原理

Set和Map类型的数据也属于异质对象&#xff0c;它们有特定的属性和方法用来操作自身。因此创建代理时&#xff0c;针对特殊的方法需要特殊的对待。 Vue 的ref 是基于reactive函数实现的&#xff0c;它在其基础上&#xff0c;增加了基本类型的响应性、解决reactive在解构时丢失…...

Python自然语言处理库之NLTK与spaCy使用详解

概要 自然语言处理(NLP)是人工智能和数据科学领域的重要分支,致力于让计算机理解、解释和生成人类语言。在Python中,NLTK(Natural Language Toolkit)和spaCy是两个广泛使用的NLP库。本文将详细介绍NLTK和spaCy的特点、功能及其使用方法,并通过具体示例展示如何使用这两…...

Hive-内部表和外部表

区别 内部表实例 准备数据 查看数据 删除数据 外部表实例 准备数据 查看数据 删除数据 区别 内部表&#xff1a;管理元数据&#xff08;记录数据的文件和目录的信息&#xff09;和数据。当删除内部表时&#xff0c;会删除数据和表的元数据&#xff0c;所以当多个表关…...

Java并发编程(三)

Java并发编程 1、什么是 Executors 框架 Executors框架是一个根据一组执行策略调用&#xff0c;调度&#xff0c;执行和控制的异步任务的框架。 无限制的创建线程会引起应用程序内存溢出。所以创建一个线程池是个更好的的解决方案&#xff0c;因为可以限制线程的数量并且可以…...

Flink Doirs Connector 常见问题:Doris目前不支持流读

常见问题 Doris Source 在数据读取完成后&#xff0c;流为什么就结束了&#xff1f; 目前 Doris Source 是有界流&#xff0c;不支持 CDC 方式读取。 问题&#xff1a;对于 Flink Doris DataStream&#xff0c;Flink 想要在 流式读取 Doirs / 实时读 Doris&#xff0c;目前读…...

期末复习资料——计算机系统基础

第一章 1、下列关于机器字长、指令字长和存储字长的说法中&#xff0c;正确的时_②、③_ ①三者在数值上总是相等的。②三者在数值上可能不相等。③存储字长是存放在一个存储单元中的二进制代码位数。④数据字长就是MDR的位数。 机器字长、指令字长和存储字长&#xff0c;三…...

一天搞定Recat(5)——ReactRouter(上)【已完结】

Hello&#xff01;大家好&#xff0c;今天带来的是React前端JS库的学习&#xff0c;课程来自黑马的往期课程&#xff0c;具体连接地址我也没有找到&#xff0c;大家可以广搜巡查一下&#xff0c;但是总体来说&#xff0c;这套课程教学质量非常高&#xff0c;每个知识点都有一个…...

TCP/IP 网络模型详解(二)之输入网址到网页显示的过程

当键入网址后&#xff0c;到网页显示&#xff0c;其间主要发生了以下几个步骤&#xff1a; 一、解析URL 下图是URL各个元素所表示的意义&#xff1a; 右边蓝色部分&#xff08;文件的路径名&#xff09;可以省略。当没有该数据时&#xff0c;代表访问根目录下事先设置的默认文…...

【k8s故障处理篇】calico-kube-controllers状态为“ImagePullBackOff”解决办法

【k8s故障处理篇】calico-kube-controllers状态为“ImagePullBackOff”解决办法 一、环境介绍1.1 本次环境规划1.2 kubernetes简介1.3 kubernetes特点二、本次实践介绍2.1 本次实践介绍2.2 报错场景三、查看报错日志3.1 查看pod描述信息3.2 查看pod日志四、报错分析五、故障处理…...

SAP PP学习笔记31 - 计划运行的步骤2 - Scheduling(日程计算),BOM Explosion(BOM展开)

上一章讲了计划运行的5大步骤中的前两步&#xff0c;计算净需求和计算批量大小。 SAP PP学习笔记30 - 计划运行的步骤1 - Net requirements calculation 计算净需求(主要讲了安全库存要素)&#xff0c;Lot-size calculation 计算批量大小-CSDN博客 本章继续讲计划运行的后面几…...

[vue3]配置@指向src

在vit.config.ts里的export default defineConfig添加以下语句 resolve: {alias: {"": "/src", // 配置指向src目录},},...

【多模态大模型】 BLIP in ICML 2022

一、引言 论文&#xff1a; BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation 作者&#xff1a; Salesforce Research 代码&#xff1a; BLIP 特点&#xff1a; 该方法分别使用ViT和BERT进行图像和文本特征提取&am…...

Flutter开发Dart 中的 mixin、extends 和 implements

目录 ​​​​​​​前言 1.extends 2.implements 3.mixin 前言 在 Dart 中&#xff0c;mixin、extends 和 implements 是面向对象编程中常用的关键字&#xff0c;它们分别用于不同的继承和实现方式。理解它们的用法和区别对于编写高质量、可维护的 Dart 代码至关重要。本文…...

SAPUI5基础知识20 - 对话框和碎片(Dialogs and Fragments)

1. 背景 在 SAPUI5 中&#xff0c;Fragments 是一种轻量级的 UI 组件&#xff0c;类似于视图&#xff08;Views&#xff09;&#xff0c;但它们没有自己的控制器&#xff08;Controller&#xff09;。Fragments 通常用于定义可以在多个视图中重用的 UI 片段&#xff0c;从而提…...

告别重复造轮子:用快马AI一键生成Unity通用数据管理模块,提升开发效率

今天想和大家分享一个提升Unity开发效率的实用技巧——如何快速构建一个通用的游戏数据管理模块。这个模块可以帮我们告别重复造轮子的痛苦&#xff0c;把更多精力放在游戏核心玩法的开发上。 为什么需要通用数据管理模块 在Unity开发中&#xff0c;我们经常需要处理各种游戏数…...

Kubernetes与存储管理最佳实践

Kubernetes与存储管理最佳实践 1. Kubernetes存储模型 Kubernetes存储模型定义了如何在容器化环境中管理和使用存储资源&#xff0c;是集群存储管理的基础。 1.1 存储模型核心概念 Volume&#xff1a;Pod中的存储卷&#xff0c;可被多个容器共享PersistentVolume (PV)&#xff…...

利用NSGA-III算法优化随机森林模型超参数的实践与可视化展示:从理论到实现的全过程解析

利用NSGA-III算法优化机器学习模型 通过Optuna库实现机器学习模型超参数的优化与可视化&#xff0c;通过精心设计的目标函数&#xff0c;将搜索多个超参数空间&#xff0c;最终确定使模型性能最优的参数组合 为了更直观地展示调参过程&#xff0c;最后利用3D曲面图对调参效果进…...

斯坦福+哈佛医学院:虚拟细胞图像生成基础模型

摘要 构建能在计算机中模拟细胞行为的虚拟细胞&#xff0c;是计算生物学的核心目标。本文提出&#xff11;款图像生成模型CellFluxV2&#xff0c;可预测化学与遗传扰动下细胞形态的变化。CellFluxV2的核心创新在于&#xff0c;通过流匹配&#xff08;flow matching&#xff09…...

Java实战:阿里云OSS文件操作工具类封装与优化

1. 阿里云OSS基础认知与Java集成准备 第一次接触阿里云OSS时&#xff0c;我完全被文档里那些专业术语搞懵了。后来才明白&#xff0c;它本质上就是个超级网盘&#xff0c;只不过比我们平时用的网盘更专业、更稳定。想象一下&#xff0c;你有个无限容量的保险箱&#xff0c;可以…...

NLP-StructBERT在跨语言语义匹配中的惊艳效果案例

NLP-StructBERT在跨语言语义匹配中的惊艳效果案例 最近在做一个国际化产品的语义搜索功能时&#xff0c;遇到了一个挺头疼的问题&#xff1a;用户用中文提问&#xff0c;但我们的知识库里有大量优质的英文资料。传统的做法是先把问题翻译成英文&#xff0c;再去搜索&#xff0…...

3分钟上手VSCode Mermaid Preview:在IDE中实现可视化图表实时预览

3分钟上手VSCode Mermaid Preview&#xff1a;在IDE中实现可视化图表实时预览 【免费下载链接】vscode-mermaid-preview Previews Mermaid diagrams 项目地址: https://gitcode.com/gh_mirrors/vs/vscode-mermaid-preview 还在为编写Mermaid图表时需要在代码编辑器与预览…...

Ubuntu上彻底卸载Ollama的保姆级命令指南(附残留文件清理)

Ubuntu上彻底卸载Ollama的深度清理指南&#xff1a;从基础命令到系统级排查 在AI工具快速迭代的今天&#xff0c;许多开发者都会在本地环境测试各种大模型框架。Ollama作为轻量级的大模型运行工具&#xff0c;虽然安装便捷&#xff0c;但当需要彻底移除时&#xff0c;简单的删除…...

javase的第一次博客

1&#xff0c;计算机简介&#xff1a;用于数据计算和处理2&#xff0c;计算机的硬件和软件&#xff1a;计算机硬件&#xff1a;运算器&#xff0c;控制器&#xff0c;存储器&#xff0c;输入设备&#xff0c;输出设备&#xff08;冯 诺依曼模型&#xff09;CPU&#xff1a;运算…...

开源工具Wand Enhancer功能解锁技术指南

开源工具Wand Enhancer功能解锁技术指南 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/gh_mirrors/we/Wand-Enhancer Wand Enhancer作为一款开源工具&#xff0c;通过本地验证技术为…...