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

常见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() 为例 - 阮一峰的网络日志

【2】React Hooks 入门教程 - 阮一峰的网络日志

相关文章:

常见React Hooks 钩子函数用法

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

AlGaN/GaN HEMT 中缓冲区相关电流崩溃的缓冲区电位模拟表征

标题&#xff1a;Characterization of Buffer-Related Current Collapse by Buffer Potential Simulation in AlGaN/GaN HEMTs 来源&#xff1a;IEEE TRANSACTIONS ON ELECTRON DEVICES (18年) 摘要 - 在本文中&#xff0c;通过使用脉冲 I-V 测量和二维漂移扩散模拟研究了 Al…...

深入理解ClickHouse跳数索引

一、跳数索引​ 影响ClickHouse查询性能的因素很多。在大多数场景中&#xff0c;关键因素是ClickHouse在计算查询WHERE子句条件时是否可以使用主键。因此&#xff0c;选择适用于最常见查询模式的主键对于表的设计至关重要。 然而&#xff0c;无论如何仔细地调优主键&#xff…...

ElasticSearch中实际操作细节点

ElasticSearch中的细节点 文章目录 ElasticSearch中的细节点1、提示&#xff1a;1.1 ElasticSearch相关文档&#xff1a;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&#xff1a;显示指定目录下的文件目录清单&#xff08;list&#xff09; cd&#xff1a;切换目录&#xff0c;改变当前的工作目录&#xff08;change directory&#xff09; cd ~ 或 cd 切换到用户主目录&#xff08;用户家…...

AI:62-基于深度学习的人体CT影像肺癌的识别与分类

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

数字孪生智慧工厂3D无代码编辑工具提供强大、简单功能

相比传统的2D/2.5D&#xff0c;3d可视化场景脱颖而出&#xff0c;成为更多行业的首选&#xff0c;然而传统的3D可视化场景制作需要花费大量的人力财力及周期来创建复杂的3D模型和场景&#xff0c;对很多企业及个人来说是个挑战&#xff0c;3D可视化场景编辑器通过简单的拖拉拽&…...

python 为什么这么受欢迎?python的优势到底在哪里?

常言道:“流水的语言&#xff0c;铁打的Python”&#xff0c;目前它可以说是已经"睥睨天下&#xff0c;傲视群雄"了。它天生丽质&#xff0c;易于读写&#xff0c;非常实用&#xff0c;从而赢得了广泛的群众基础&#xff0c;被誉为"宇宙最好的编程语言"&am…...

Flutter转换png图片为jpg图片

1.需求 在xxx产品需求中&#xff0c;需要将png图片转为jpg图片。 2.引用库 image: ^4.1.3 Dart图像库提供了以各种图像文件格式加载、保存和操作图像的功能。 该库可以与dart:io和dart:html一起用于命令行、Flutter和web应用程序。 注&#xff1a;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函数能够读取的格式包含&#xff1a;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是改成&#xff1a;standard还是chinese都无法实现中文分词。 处理中文分词一般采用IK分词器 安装链接&…...

Git设置显示中文

git config --global i18n.comitencoding utf-8 git config --global i18n.logoutputencoding utf-8 export LESSCHARSETutf-8...

数实结合的复杂电磁环境构建解决方案

数实结合的复杂电磁环境构建解决方案 数实结合的复杂电磁环境构建 目前无线收发设备面临的电磁环境愈发恶劣。为了检验设备在复杂电磁环境下的实际工作性能&#xff0c;需进行各种应用条件下的测试和试验。外场测试难以提供各种应用环境&#xff0c;存在测试周期长、成本高、难…...

MySQL geometry 类型数据测试

MySQL的geometry类型的表的创建和测试&#xff1a; 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代码 摘要&#xff1a;本文主要介绍利用袋獾算法来优化无人机航迹规划。 1.袋獾搜索算法 …...

2024上海智博会,上海国际智慧城市,物联网,大数据展会(世亚智博会)

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

家庭教育质量提升成未来教育关注重点

随着教育改革的不断深化&#xff0c;家校合作模式也在实践中不断探索和丰富。 11 月 6 日&#xff0c;第六届长三角家校合作论坛于上海杨浦盛大开幕&#xff0c;此次论坛围绕“家校协同与人的学校领导”这一主题展开深度研讨。论坛旨在交流和分享相关经验及做法&#xff0c;以…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

Appium+python自动化(十六)- ADB命令

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

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

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

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

【笔记】WSL 中 Rust 安装与测试完整记录

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