常见React Hooks 钩子函数用法
一、useState
useState()用于为函数组件引入状态(state)。纯函数不能有状态,所以把状态放在钩子里面。
import React, { useState } from 'react'
import './Button.css'export function UseStateWithoutFunc() {const [name, setName] = useState('何遇')const [age, setAge] = useState()function onChange() {setName('张三') // 修改namesetAge(23) // 修改age}return (<><div className={'nameButton'}>姓名: {name}</div><div className={'ageButton'}>年龄: {age === undefined ? '未知' : age}</div><button onClick={onChange}>click</button></>)
}
上面代码中,UseStateWithoutFunc 组件是一个函数,内部使用useState()钩子引入状态。
useState()这个函数接受状态的初始值,作为参数,上例的初始值为显示的姓名文字。该函数返回一个数组,数组的第一个成员是一个变量(上例是name),指向状态的当前值。第二个成员是一个函数,用来更新状态,约定是set前缀加上状态的变量名(上例是setName)。
当没有赋予初始值的时候,这个变量则是undefined,没有定义的。当再次执行set函数的时候,则会被赋值。如上述年龄字段age,一开始是undefined的,所以显示出来的效果就是“未知”。
当点击button的时候,触发onChange函数,同时给年龄和姓名赋新值。因此点击按钮之后显示效果如下:
二、useEffect
seEffect()用来引入具有副作用的操作,最常见的就是向服务器请求数据。以前,放在componentDidMount里面的代码,现在可以放在useEffect()。
useEffect()的用法如下:
useEffect(() => {// Async Action
}, [dependencies]);
上面用法中,useEffect()接受两个参数。
- 第一个参数是一个函数,异步操作的代码放在里面。
- 第二个参数是一个数组,用于给出 Effect 的依赖项,只要这个数组发生变化,useEffect()就会执行。第二个参数可以省略,这时每次组件渲染时,就会执行useEffect()。
下面是Person.js和Person.css代码
import {useEffect, useState} from "react";
import "./Person.css";const Person = ({personId}) => {const[loading, setLoading] = useState(true);const[person, setPerson] = useState({});useEffect(() => {setLoading(true);fetch(`https://swapi.dev/api/people/${personId}`).then(response => response.json()).then(data => {setLoading(false)setPerson(data)});}, [personId]);if (loading) {return <p>Loading...</p>}return <div><p>You're viewing: {person.name}</p><p>Height: {person.height}</p><p>Mass: {person.mass}</p></div>
}export default function PersonComponent() {const [show, setShow] = useState("1");return (<div className="App"><Person personId={show}></Person><div>Show:<button onClick={() => setShow("3")}>R2-D2</button><button onClick={() => setShow("2")}>C-3PO</button></div></div>)
}
* {margin: 0;padding: 0;
}
body {padding: 10px;background-color: #f5f5fa;color: #222;
}
h2 {margin-bottom: 20px;font-family: 'Helvetica';font-weight: 400;
}
.App {font-family: 'Helvetica';font-weight: 200;text-align: left;width: 400px;
}
input {border: 1px solid #ddd;background-color: #fff;padding: 5px 10px;margin: 10px 0;border-radius: 5px;width: 300px;
}
button {padding: 5px 20px;background: #0066cc;border: 1px solid #fff;border-radius: 15px;color: #fff;margin-top: 10px;margin-bottom: 10px;
}
button:hover {cursor: pointer;box-shadow: 0px 2px 4px #0044aa40;
}
button:active {background: #0044aa;
}
button:focus {outline:0;}
ul {margin-left: 20px;
}.navbar {display: flex;flex-direction: row;justify-content: space-between;padding-bottom: 10px;margin-bottom: 20px;border-bottom: 1px solid #ccc;
}
.messages h1 {margin-bottom: 20px;
}
.messages p {margin-bottom: 10px;
}
.message {background-color: #fff;border: 1px solid #ddd;padding: 10px;border-radius: 4px;
}
在请求https://swapi.dev/api/people/{personId}/ 这个接口,每次传入不同的personId值,就可以请求到不同人的数据。
每次personId发生改变之后,Person组件里的useEffect里的方法就会执行一次也就是会去请求一次后端数据,请求到了之后再刷新界面。没有请求到的时候由于loading默认设为true,因此就会执行return <p>Loading...</p>这段代码,就会展示Loading的文字。等请求到之后,会执行这行 setLoading(false),将loading字段设为false,因此此时就不会展示Loading的文字,而是展示姓名、身高等字样。
点击R2-D2数据还没请求到的时候,会显示Loading
请求到对应的数据之后,就会展示对应的个人信息
三、useReducer
React 本身不提供状态管理功能,通常需要使用外部库。这方面最常用的库是 Redux。
Redux 的核心概念是,组件发出 action 与状态管理器通信。状态管理器收到 action 以后,使用 Reducer 函数算出新的状态,Reducer 函数的形式是(state, action) => newState。
useReducers()钩子用来引入 Reducer 功能。
const [state, dispatch] = useReducer(reducer, initialState);
上面是useReducer()的基本用法,它接受 Reducer 函数和状态的初始值作为参数,返回一个数组。数组的第一个成员是状态的当前值,第二个成员是发送 action 的dispatch函数。
下面是一个计数器的例子。用于计算状态的 Reducer 函数如下。
const myReducer = (state, action) => {switch(action.type) {case('countUp'):return {...state,count: state.count + 1}default:return state;}
}
组件代码如下。
export default function UseReducerComponent() {const[state, dispatch] = useReducer(myReducer, {count: 0})return (<div className="App"><button onClick={() => dispatch({type: 'countUp'})}>+1</button><p>Count: {state.count}</p></div>)
}
import {useReducer} from "react";
import "./styles.css";const myReducer = (state, action) => {switch (action.type) {case ('countUp'):return {...state,count: state.count + 1}default:return state}
}export default function UseReducerComponent() {const[state, dispatch] = useReducer(myReducer, {count: 0})return (<div className="App"><button onClick={() => dispatch({type: 'countUp'})}>+1</button><p>Count: {state.count}</p></div>)
}
styles.css样式如下:
* {margin: 0;padding: 0;
}
body {padding: 10px;background-color: #f5f5fa;color: #222;
}
h2 {margin-bottom: 20px;font-family: 'Helvetica';font-weight: 400;
}
.App {font-family: 'Helvetica';font-weight: 200;text-align: left;width: 400px;
}
input {border: 1px solid #ddd;background-color: #fff;padding: 5px 10px;margin: 10px 0;border-radius: 5px;width: 300px;
}
button {padding: 5px 20px;background: #0066cc;border: 1px solid #fff;border-radius: 15px;color: #fff;margin-top: 10px;margin-bottom: 10px;
}
button:hover {cursor: pointer;box-shadow: 0px 2px 4px #0044aa40;
}
button:active {background: #0044aa;
}
button:focus {outline:0;}
ul {margin-left: 20px;
}.navbar {display: flex;flex-direction: row;justify-content: space-between;padding-bottom: 10px;margin-bottom: 20px;border-bottom: 1px solid #ccc;
}
.messages h1 {margin-bottom: 20px;
}
.messages p {margin-bottom: 10px;
}
.message {background-color: #fff;border: 1px solid #ddd;padding: 10px;border-radius: 4px;
}
四、useContext
如果需要在组件之间共享状态,可以使用useContext()。
现在有两个组件 Navbar 和 Messages,我们希望它们之间共享状态。
<div className="App"><Navbar/><Messages/>
</div>
第一步就是使用 React Context API,在组件外部建立一个 Context。
const AppContext = React.createContext({});
组件封装代码如下。
<AppContext.Provider value={{username: 'superawesome'
}}><div className="App"><Navbar/><Messages/></div>
</AppContext.Provider>
上面代码中,AppContext.Provider提供了一个 Context 对象,这个对象可以被子组件共享。
Navbar 组件的代码如下。下面代码中,useContext()钩子函数用来引入 Context 对象,从中获取username属性
const Navbar = () => {const { username } = useContext(AppContext);return (<div className="navbar"><p>AwesomeSite</p><p>{username}</p></div>);
}
Message 组件的代码如下。下面代码中,useContext()钩子函数用来引入 Context 对象,从中获取username属性
const Messages = () => {const { username } = useContext(AppContext)return (<div className="messages"><h1>Messages</h1><p>1 message for {username}</p><p className="message">useContext is awesome!</p></div>)
}
UseContextComponent.js代码如下所示:
import React, { useContext } from "react";
import "./style.css";const AppContext = React.createContext({});const Navbar = () => {const { username } = useContext(AppContext)return (<div className="navbar"><p>AwesomeSite</p><p>{username}</p></div>)
}const Messages = () => {const { username } = useContext(AppContext)return (<div className="messages"><h1>Messages</h1><p>1 message for {username}</p><p className="message">useContext is awesome!</p></div>)
}export default function UseContextComponent() {return (<AppContext.Provider value={{username: 'superawesome'}}><div className="App"><Navbar /><Messages /></div></AppContext.Provider>);
}
style.css文件如下:
* {margin: 0;padding: 0;
}
body {padding: 10px;background-color: #f5f5fa;color: #222;
}
h2 {margin-bottom: 20px;font-family: 'Helvetica';font-weight: 400;
}
.App {font-family: 'Helvetica';font-weight: 200;text-align: left;width: 400px;
}
input {border: 1px solid #ddd;background-color: #fff;padding: 5px 10px;margin: 10px 0;border-radius: 5px;width: 300px;
}
button {padding: 5px 20px;background: #0066cc;border: 1px solid #fff;border-radius: 15px;color: #fff;margin-top: 10px;margin-bottom: 10px;
}
button:hover {cursor: pointer;box-shadow: 0px 2px 4px #0044aa40;
}
button:active {background: #0044aa;
}
button:focus {outline:0;}
ul {margin-left: 20px;
}.navbar {display: flex;flex-direction: row;justify-content: space-between;padding-bottom: 10px;margin-bottom: 20px;border-bottom: 1px solid #ccc;
}
.messages h1 {margin-bottom: 20px;
}
.messages p {margin-bottom: 10px;
}
.message {background-color: #fff;border: 1px solid #ddd;padding: 10px;border-radius: 4px;
}
可以理解为一种共享上下文状态。类似于Android里context的一样,获取上下文信息的。
第一块是组件Navbar展示的
第二块是组件Message展示的
引用文献:
【1】轻松学会 React 钩子:以 useEffect() 为例 - 阮一峰的网络日志
相关文章:

常见React Hooks 钩子函数用法
一、useState useState()用于为函数组件引入状态(state)。纯函数不能有状态,所以把状态放在钩子里面。 import React, { useState } from react import ./Button.cssexport function UseStateWithoutFunc() {const [name, setName] useStat…...

AlGaN/GaN HEMT 中缓冲区相关电流崩溃的缓冲区电位模拟表征
标题:Characterization of Buffer-Related Current Collapse by Buffer Potential Simulation in AlGaN/GaN HEMTs 来源:IEEE TRANSACTIONS ON ELECTRON DEVICES (18年) 摘要 - 在本文中,通过使用脉冲 I-V 测量和二维漂移扩散模拟研究了 Al…...

深入理解ClickHouse跳数索引
一、跳数索引 影响ClickHouse查询性能的因素很多。在大多数场景中,关键因素是ClickHouse在计算查询WHERE子句条件时是否可以使用主键。因此,选择适用于最常见查询模式的主键对于表的设计至关重要。 然而,无论如何仔细地调优主键ÿ…...
ElasticSearch中实际操作细节点
ElasticSearch中的细节点 文章目录 ElasticSearch中的细节点1、提示:1.1 ElasticSearch相关文档:1.2 Kibana的常用快捷键1.3 kibana的注释方式 2、term与terms的用法以及区别3、ElasticSearch中"index":"false","doc_values&qu…...
VCG 获取指定面片与顶点的索引
文章目录 一、介绍二、实现代码三、实现效果参考资料一、介绍 VCG Lib存在许多中方式对Mesh数据进行编码,其中最为常用的为顶点+三角形(比如三角形网格以及四面体网格)。VCG关于Mesh的定义如下所示: vcg::tri::TriMesh 包含顶点的容器类型(通常是std::vector),具体的顶点…...

开发知识点-Django
Django 1 了解简介2 Django项目结构3 url 地址 和视图函数4 路由配置5 请求及响应6 GET请求和POST请求查询字符串 7 Django设计模式及模板层8 模板层-变量和标签9 模板层-过滤器和继承继承 重写 10 url反向解析11 静态文件12 Django 应用及分布式路由创建之后 注册 一下 13 模型…...
Linux系统笔记参考
Linux系统笔记 一、基本命令 1、简单的几个命令 ls:显示指定目录下的文件目录清单(list) cd:切换目录,改变当前的工作目录(change directory) cd ~ 或 cd 切换到用户主目录(用户家…...

AI:62-基于深度学习的人体CT影像肺癌的识别与分类
🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…...

数字孪生智慧工厂3D无代码编辑工具提供强大、简单功能
相比传统的2D/2.5D,3d可视化场景脱颖而出,成为更多行业的首选,然而传统的3D可视化场景制作需要花费大量的人力财力及周期来创建复杂的3D模型和场景,对很多企业及个人来说是个挑战,3D可视化场景编辑器通过简单的拖拉拽&…...

python 为什么这么受欢迎?python的优势到底在哪里?
常言道:“流水的语言,铁打的Python”,目前它可以说是已经"睥睨天下,傲视群雄"了。它天生丽质,易于读写,非常实用,从而赢得了广泛的群众基础,被誉为"宇宙最好的编程语言"&am…...
Flutter转换png图片为jpg图片
1.需求 在xxx产品需求中,需要将png图片转为jpg图片。 2.引用库 image: ^4.1.3 Dart图像库提供了以各种图像文件格式加载、保存和操作图像的功能。 该库可以与dart:io和dart:html一起用于命令行、Flutter和web应用程序。 注:4.0是该库先前版本的主要修订…...
c++ grpc 第一个用例
一、linux 包管理工具安装 sudo apt-get update sudo apt-get install -y build-essential autoconf libtool pkg-config cmake sudo apt-get install -y libgflags-dev libgtest-dev sudo apt-get install -y clang libc-dev# 安装 gRPC C 相关依赖 sudo apt-get install -y …...

pandas笔记:读写excel
1 读excel read_excel函数能够读取的格式包含:xls, xlsx, xlsm, xlsb, odf, ods 和 odt 文件扩展名。 支持读取单一sheet或几个sheet。 1.0 使用的数据 1.1 主要使用方法 pandas.read_excel(io, sheet_name0, header0, namesNone, index_colNone, usecolsNon…...

【ES分词】
分词 #测试分词器 POST /_analyze {"text": "小米手机和华为手机都是国产mobilephone", "analyzer": "english" }不管analyzer是改成:standard还是chinese都无法实现中文分词。 处理中文分词一般采用IK分词器 安装链接&…...

Git设置显示中文
git config --global i18n.comitencoding utf-8 git config --global i18n.logoutputencoding utf-8 export LESSCHARSETutf-8...

数实结合的复杂电磁环境构建解决方案
数实结合的复杂电磁环境构建解决方案 数实结合的复杂电磁环境构建 目前无线收发设备面临的电磁环境愈发恶劣。为了检验设备在复杂电磁环境下的实际工作性能,需进行各种应用条件下的测试和试验。外场测试难以提供各种应用环境,存在测试周期长、成本高、难…...
MySQL geometry 类型数据测试
MySQL的geometry类型的表的创建和测试: CREATE TABLE geom_test01( id INT NOT NULL PRIMARY KEY, info varchar(100), geom GEOMETRY ); desc geom_test01; insert into geom_test01 (id,info,geom) values (1, geom, geomfromtext(MULTIPOLYGON(((1 1…...

基于袋獾算法的无人机航迹规划-附代码
基于袋獾算法的无人机航迹规划 文章目录 基于袋獾算法的无人机航迹规划1.袋獾搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要:本文主要介绍利用袋獾算法来优化无人机航迹规划。 1.袋獾搜索算法 …...

2024上海智博会,上海国际智慧城市,物联网,大数据展会(世亚智博会)
中国国际智慧城市,物联网,大数据博览会(简称:世亚智博会)自2010年创办以来,至今已成功举办十多届。世亚智博会是中国较高、规模较大、影响力较广的展会;是被国际业界公认的不可错过的名展之一。随着世亚智博会的国际地位和影响不断…...

家庭教育质量提升成未来教育关注重点
随着教育改革的不断深化,家校合作模式也在实践中不断探索和丰富。 11 月 6 日,第六届长三角家校合作论坛于上海杨浦盛大开幕,此次论坛围绕“家校协同与人的学校领导”这一主题展开深度研讨。论坛旨在交流和分享相关经验及做法,以…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...