React 中的 useRef 与 useState
React 是一个流行的 JavaScript 库,用于构建用户界面。它提供了几个钩子,使开发人员能够管理状态并执行副作用。 React 中两个常用的钩子是 useRef 和 useState 。虽然它们乍一看似乎很相似,但它们具有不同的目的并且具有不同的用例。在本文中,我们将深入探讨 useRef 和 useState ,比较它们的功能并提供示例来说明它们的用法。
理解 useRef :
React 中的 useRef 钩子创建了一个在组件呈现之间持续存在的可变引用。与管理状态并触发重新渲染的 useState 不同, useRef 主要用于访问和操作 DOM 或存储不触发重新渲染的可变值。它返回一个带有 current 属性的可变对象。
示例 1:访问 DOM 元素
假设我们想在单击按钮时关注输入字段。我们可以使用 useRef 来实现这一点,如下所示:
import React, { useRef } from 'react';
function MyComponent() {
const inputRef = useRef(null);
const handleClick = () => {
inputRef.current.focus();
};
return (
<div>
<input ref={inputRef} />
<button onClick={handleClick}>Focus Input</button>
</div>
);
}
在上面的示例中,我们使用 useRef 创建一个 ref 并将其分配给 inputRef 变量。我们将 inputRef 传递给输入元素的 ref 属性,使其可用于访问输入的 DOM 节点。单击按钮时,将执行 handleClick 函数,并调用 inputRef.current.focus() 以聚焦于输入字段。
理解 useState :
useState 挂钩用于管理功能组件内的状态。它允许我们创建可以更新的变量,并在其值发生变化时触发重新渲染。 useState 钩子返回一个包含两个元素的数组:当前状态值和更新它的函数。
示例 2:管理计数器
让我们使用 useState 创建一个简单的计数器组件:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
在上面的代码中,我们使用数组解构语法来分配 count 状态变量和 setCount 函数来更新它。使用 useState(0) 将 count 的初始值设置为 0 。单击按钮时,将调用 increment 函数,通过添加 1 更新 count 状态。结果,组件重新渲染,反映 count 的更新值。
比较 useRef 和 useState :
虽然 useRef 和 useState 都可以存储值,但它们有不同的用途:
- 管理状态:
useState旨在管理组件内的状态。当状态更新时,它会触发重新渲染,确保 UI 反映最新值。 - 访问和操作 DOM:
useRef主要用于与 DOM 交互,例如访问输入值或关注元素。它允许我们存储对 DOM 节点的引用并检索它们的属性,而无需触发重新渲染。 - 跨渲染保留值:
useRef在组件渲染之间维护相同的值,而useState在每次渲染期间初始化状态。 - 重新渲染行为:更新
useState返回的值会导致组件重新渲染,同时更新使用useRef的current属性 不会触发重新渲染。
用例:
为了进一步了解 useRef 和 useState 的用例,让我们探讨一下每个钩子更适合的一些场景:
1. useRef 用例:
1.1. 访问 DOM 元素:当您需要访问或操作 DOM 元素(例如聚焦输入、滚动到特定元素或测量元素的大小)时, useRef 是合适的选择。它允许您创建对 DOM 节点的引用并访问其属性或方法。
1.2. 存储可变值:如果您有一个值需要在渲染过程中保留,但不会影响组件的 UI 或触发重新渲染, useRef 是一个不错的选择。例如,您可以使用 useRef 存储以前的值、缓存值或保留可变值以进行比较。
2. useState 用例:
2.1. 管理组件状态:当您需要管理和更新组件内的状态时,建议使用 useState 方法。它提供了一种存储和更新影响组件 UI 并触发重新渲染的值的方法。
2.2. 处理用户交互:如果组件中有交互元素(例如复选框、输入字段或切换开关),则通常使用 useState 来管理与这些交互相关的状态。您可以根据用户输入更新状态并反映 UI 中的更改。
对比示例:
为了更清楚地说明 useRef 和 useState 之间的区别,让我们考虑一个可以使用两个钩子的示例:
假设我们有一个带有输入字段和提交按钮的表单。当用户单击提交按钮时,我们希望在不清除输入字段的情况下显示成功消息。
使用 useRef:
import React, { useRef } from 'react';
function Form() {
const inputRef = useRef(null);
const handleSubmit = () => {
const value = inputRef.current.value;
// 提交表单
displaySuccessMessage();
};
const displaySuccessMessage = () => {
// 显示成功消息而不清除输入字段
};
return (
<div>
<input ref={inputRef} />
<button onClick={handleSubmit}>Submit</button>
</div>
);
}
在此示例中,我们使用 useRef 创建对输入字段的引用。单击提交按钮后,我们使用 inputRef.current.value 访问输入字段的值并继续提交表单。输入字段的值未清除,因为我们没有更新状态或触发重新渲染。
使用 useState :
import React, { useState } from 'react';
function Form() {
const [inputValue, setInputValue] = useState('');
const handleSubmit = () => {
// 提交表单
displaySuccessMessage();
};
const displaySuccessMessage = () => {
// 展示成功消息
setInputValue(''); // 清理输入内容
};
const handleInputChange = (e) => {
setInputValue(e.target.value);
};
return (
<div>
<input value={inputValue} onChange={handleInputChange} />
<button onClick={handleSubmit}>Submit</button>
</div>
);
}
在这个版本中,我们使用 useState 来管理输入字段的状态。我们使用 useState('') 用空字符串初始化 inputValue 状态。当用户在输入字段中键入内容时,将调用 handleInputChange 函数,更新状态并触发重新渲染以反映新值。单击提交按钮时,将执行 handleSubmit 函数,该函数显示成功消息并通过将 inputValue 状态设置为空字符串来清除输入字段。
在此示例中, useState 用于管理输入字段的值并在用户与其交互时触发重新渲染。 displaySuccessMessage 中的状态更新通过更新 inputValue 状态来清除输入字段。
结论:
总之, useRef 和 useState 都是React中必不可少的钩子,但它们有不同的用途。 useRef 主要用于访问和操作 DOM 或存储可变值而不触发重新渲染。它提供了一个在组件呈现之间持续存在的可变引用。另一方面, useState 用于管理组件状态,当状态更新时触发重新渲染。它返回一个状态值和一个更新它的函数。
了解 useRef 和 useState 之间的差异并了解何时使用每个钩子对于编写有效且优化的 React 组件至关重要。通过正确利用 useRef 和 useState ,您可以使用 React 构建交互式和高性能应用程序。
谢谢阅读!
我希望您觉得这篇文章有用。如果您有任何疑问或建议,请留言。您的反馈帮助我变得更好。
React 中的 useRef 与 useState的更多相关文章
- 用React 中的useState改变值不重新渲染的问题
不渲染 const [lists,setLists] =useState([]); ..... const arr = lists; arr.splice(index,1) //根据删除index下标 ...
- 在React中使用 react-router-dom 编程式路由导航的正确姿势【含V5.x、V6.x】
## react-router-dom 编程式路由导航 (v5) ###### 1.push跳转+携带params参数 ```jsx props.history.push(`/b/child1/${i ...
- React 中阻止事件冒泡的问题
在正式开始前,先来看看 JS 中事件的触发与事件处理器的执行. JS 中事件的监听与处理 事件捕获与冒泡 DOM 事件会先后经历 捕获 与 冒泡 两个阶段.捕获即事件沿着 DOM 树由上往下传递,到达 ...
- 哪种方式更适合在React中获取数据?
作者:Dmitri Pavlutin 译者:小维FE 原文:dmitripavlutin.com 国外文章,笔者采用意译的方式,以保证文章的可读性. 当执行像数据获取这样的I/O操作时,你必须发起获取 ...
- 解读vue-server-renderer源码并在react中的实现
前言 在博客开发的过程中,有这样一个需求想解决,就是在SSR开发环境中,服务端的代码是是直接通过webpack打包成文件(因为里面包含同构的代码,就是服务端与客户端共享前端的组件代码),写到磁盘里 ...
- 前端必读2.0:如何在React 中使用SpreadJS导入和导出 Excel 文件
最近我们公司接到一个客户的需求,要求为正在开发的项目加个功能.项目的前端使用的是React,客户想添加具备Excel 导入/导出功能的电子表格模块. 经过几个小时的原型构建后,技术团队确认所有客户需求 ...
- react中redux怎么使用
一.redux是什么? redux 就是react 全局状态管理,作用是存放全局数据 二.核心 state:存放数据 reducer:修改仓库数据 是一个函数,参数一:仓库中的数据,参数2:行为 ac ...
- 在react中使用wangEditorV5
wangEditor是基于JavaScript和css的一款web富文本编辑器,是国内比较好用的一款轻量级富文本编辑器,上手简单,易用且开源免费. 官方文档:http://www.wangeditor ...
- 理解React中es6方法创建组件的this
首发于:https://mingjiezhang.github.io/(转载请说明此出处). 在JavaScript中,this对象是运行时基于函数的执行环境(也就是上下文)绑定的. 从react中的 ...
- 【原】React中,map出来的元素添加事件无法使用
在使用react中,经常用到react的map函数,用法和jquery里中的map一样,但是,如果你在每个map出来的元素中添加,你会发觉添加的事件无法关联, 比如,我们很多的评论,我需要在每个评论下 ...
随机推荐
- Python 爬虫之 xpath
0x01 XML 基础 xpath 是在 XML 文档中搜索内容的一门语言 HTML 是 XML 的一个子集 XML 代码举例: <book> <isbn>978xxxxxxx ...
- Web 在线制表工具稳定吗?和桌面报表工具对比哪个好用?
报表工具中最成熟常用的基本都是桌面设计器,但是 web 在线制表工具也占有部分市场,这是因为它也有一些优点: 1.报表设计和发布都在 web 端,无需额外安装桌面设计器 2.web 在线制表工具可直接 ...
- mysql 必知必会整理—视图[十二]
前言 简单整理一下视图. 正文 视图: 需要MySQL 5 MySQL 5添加了对视图的支持.因此,本章内容适用于MySQL 5及以后的版本. 视图是虚拟的表.与包含数据的表不一样,视图只包含使用时动 ...
- gitlib配置
第1步:下载Java并安装Java.一般来说下载jdk对应的版本就行. 第2步:配置Java环境变量,具体如下: 1. 新建:变量名:JAVA_HOME:变量值:C:\Program Files\Ja ...
- Worker 进行多线程任务开发
概念介绍 在 OpenHarmony 中,UI 线程负责处理 UI 事件和用户交互,而 Worker 线程用于处理耗时操作,以提高应用程序的响应速度和用户体验. Worker 线程是与主线程并行的独立 ...
- 他来了他来了,.net开源智能家居之苹果HomeKit的c#原生sdk【Homekit.Net】1.0.0发布,快来打造你的私人智能家居吧
背景介绍 hi 大家好,我是三合,作为一个非著名懒人,每天上完班回到家,瘫在沙发上一动都不想动,去开个灯我都嫌累,此时,智能家居拯救了我,只需要在手机点点点,开关灯,空调,窗帘就都搞定了,一开始我用的 ...
- 动态尺寸模型优化实践之Shape Constraint IR Part II
简介: 在本系列分享中我们将介绍BladeDISC在动态shape语义下做性能优化的一些实践和思考.本次分享的是我们最近开展的有关shape constraint IR的工作,Part II 中我们将 ...
- 龙蜥社区开源 coolbpf,BPF 程序开发效率提升百倍 | 龙蜥技术
简介: coolbpf,可以酷玩的BPF!来看看让BPF加了双翅膀的它究竟有多硬核? 文/系统运维 SIG(Special Interest Group) 引言 BPF 是一个新的动态跟踪技术,目前这 ...
- 高效使用Java构建工具|Maven篇|云效工程师指北
简介:高效使用Java构建工具|Maven篇.众所周知,当前最主流的Java构建工具为Maven/Gradle/Bazel,针对每一个工具,我将分别从日常工作中常见的场景问题切入,例如依赖管理.构建 ...
- 使用 Arthas 排查开源 Excel 组件问题
简介: 有了实际的使用之后,不免会想到,Arthas 是如何做到在程序运行时,动态监测我们的代码的呢?带着这样的问题,我们一起来看下 Java Agent 技术实现原理. 背景介绍 项目中有使 ...