React18学习笔记(五) 【总结】常用的React Hooks函数,常用React-Redux Hooks函数和React中的组件通信 - 指南
文章目录
- 一.常用React Hooks函数
- 1.useState - 状态管理
- 2.useEffect - 副作用处理
- 3.useRef - 引用DOM或存储可变值
- 4.useMemo - 记忆化计算结果
- 5.useContext - 访问上下文
- 6.useCallback - 记忆化函数
- 7.自定义React Hooks函数
- 二.常用React-Redux Hooks函数
- 1.useSelector - 访问Redux Store的状态
- 2.useDispatch - 分发Action
- 3.useStore - 访问Store示例
- 三.React中的组件通信
- 1.父传子
- 2.子传父
- 3.跨层级通信
- 4.使用ref
一.常用React Hooks函数
1.useState - 状态管理
- 作用:用于在函数组件中添加状态管理,创建状态变量
- 特点:状态变量只能由其状态更新函数来更新其值,状态更新时会触发组件重新渲染
- 示例:
import {useState} from "react"
const [isVisible,setIsVisible] = useState(false)
const handleClick=()=>{
setIsVisible(!isVisible)
}
2.useEffect - 副作用处理
作用:处理组件中的副作用(数据获取,订阅,手动操作DOM等)
参数:副作用函数和依赖项
特点:在组件渲染后执行,通过依赖数组控制执行的时机
使用场景:API请求、事件监听、定时器、操作DOM
示例:
const [list,setList]=useState()
useEffect(()=>{
const getList=async()=>{
const res=await axios.get(url)
const list=res.data;
setList(list)
}
},[list])
3.useRef - 引用DOM或存储可变值
- 作用:创建可变的引用对象,其
.current属性可保存值 - 特点:更新
.current属性不会触发组件重新渲染,常用于访问DOM节点 - 常用场景:访问DOM元素、存定时器id,保存前一个状态值
- 示例:获取
input框的焦点
import { useState,useRef,useEffect } from 'react';
const inputRef=useRef(null)
const handleSubmit=()=>{
console.log('发布评论')
// 判断非空
if(inputValue.trim()==='') return;
// 发布评论
const myComment={
// rpid:`c${commentList.length+1}`,//替换成uuid
rpid:uuidV4(),//当成一个可执行方法来使用,生成独一无二的id
user:{...currentUser},
content:inputValue,
// ctime:new Date().toLocaleString('zh-CN').split(' ')[0].replace(/\//g, '-'),
ctime:dayjs(new Date()).format('MM-DD hh:mm'),
likes:0
}
// 提交新评论后:更新状态
// 1.更新评论列表
setCommentList([...commentList,myComment])
// 2.清空input输入框
setInputValue('')
// 3.获取DOM元素,文本框重新获得焦点
inputRef.current.focus();
}
......
{/* 评论输入区 */}
<div className="comment-input-area"><inputtype="text"placeholder="发个友善的评论吧..."value={inputValue}onChange={e=>setInputValue(e.target.value)}className="comment-input"ref={inputRef}/><button className='submit-btn' onClick={handleSubmit}>发布</button></div>
4.useMemo - 记忆化计算结果
- 作用:记忆化计算结果,避免每次渲染都重新计算(类似Vue中的computed和getter)
- 特点:依赖不变时返回缓存值,减少不必要的计算开销
- 注意事项:不要用于有副作用的操作并确保计算函数是纯函数
- 示例:
//pages/Month/index.js
import { useState, useMemo, useEffect } from "react";
......
// 按月分组:消费数据分组处理
const monthGroup = useMemo(() => {
// return出去计算之后的值
return _.groupBy(billList, (item) => dayjs(item.date).format("YYYY | MM"))
}, [billList])
console.log("消费数据(分组后):",monthGroup);
5.useContext - 访问上下文
- 作用:访问React上下文中的值
- 特点:避免props层层传递
- 注意事项:组件会在上下文值变化时重新渲染,当使用多个上下文时嵌套顺序会影响值获取
- 常用场景:主体切换、用户认证、多语言支持
- 示例:
// 1. 创建上下文
const ThemeContext = React.createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark"><Toolbar /></ThemeContext.Provider>);}function Toolbar() {return <ThemedButton />;}function ThemedButton() {const theme = useContext(ThemeContext);return (<button style={{background: theme === 'dark' ? '#333' : '#eee',color: theme === 'dark' ? '#fff' : '#000'}}>主题按钮</button>);}
6.useCallback - 记忆化函数
- 作用:返回记忆化的回调函数,避免每次渲染都创建新函数
- 特点:依赖不变时防止相同的函数引用,优化子组件避免不必要的重新渲染
- 注意事项:仅当函数的创建成本高或传递给子组件时使用
- 常用场景:优化子组件props、事件处理函数
- 示例:
function Parent() {
const [count, setCount] = useState(0);
// 记忆化回调函数
const increment = useCallback(() => {
setCount(c => c + 1);
}, []);
return (
<div><Child onIncrement={increment} /><p>计数: {count}</p></div>);}// 使用React.memo优化子组件const Child = React.memo(({ onIncrement }) => {console.log('子组件渲染');return <button onClick={onIncrement}>增加</button>;});
7.自定义React Hooks函数
const useToggle=()=>{
const [show,setShow]=useState(true)
const isToggle=()=>setShow(!show)
return{
show,
isToggle
}
}
const [show,isToggle]=useToggle();
<button onClick={isToggle}>{show ? "点击隐藏" : "点击显示"}</button>
二.常用React-Redux Hooks函数
1.useSelector - 访问Redux Store的状态
- 作用:从
Redux store中提取和监听状态 - 参数:一个选择器函数,接收整个state并返回需要的状态片段
- 特点:当选择的值发生变化时,组件会重新渲染
- 注意事项:选择器应简单高效,避免复杂计算,避免在
useSelector中返回新的引用类型对象 - 示例:引入后台消费数据
/*省流:只看使用部分*/
//使用----组件内(pages/Month/index.js):
import { useSelector } from "react-redux";
const Month = () => {
// 引入后台消费数据
const billList = useSelector((state) => state.bill.billList)
console.log("消费数据(原始):",billList)
}
//定义----store内(store/modules/billStore.js)
const billStore = createSlice({
name: 'bill',
initialState: {
// 账单列表
billList: [],
},
reducers: {
// 设置账单列表
setBillList(state, action) {
state.billList = action.payload
}
}
})
const { setBillList } = billStore.actions
//导出/注册----入口文件内(store/index.js)
// 组合子模块,导出store实例
import billReducer from './modules/billStore.js'
import { configureStore } from '@reduxjs/toolkit'
const store = configureStore({
reducer: {
bill: billReducer// 这里的key要和子模块的name一致,即:name: 'bill'
}
})
export default store
2.useDispatch - 分发Action
- 功能:获取
Redux store的dispatch函数引用 - 特点:返回的dispatch引用时稳定的,不会随着渲染改变
- 最佳实践:把dispatch逻辑封装在回调函数中
- 示例:
//page/Layout/index.js----在useEffect中dispatch存于store中的Action异步方法
import { useDispatch } from 'react-redux'
import { useEffect } from "react";
const Layout = () => {
const dispatch = useDispatch()
useEffect(() => {// 组件挂载完成之后,执行异步请求消费数据列表(账单)
dispatch(getBillList())
}, [dispatch])
.....
}
//store/modules/billStore.js----store中的异步方法:
// 异步获取账单列表
const getBillList = () => {
return async (dispatch) => {
const res = await axios.get('http://localhost:8888/list')
dispatch(setBillList(res.data))
}
}
export { getBillList }
3.useStore - 访问Store示例
- 功能:获取整个
Redux store实例引用(不常用) - 使用场景:特定情况下须知直接访问整个
store对象时,如手动订阅 - 注意事项:大多数情况下应优先使用
useSelector而非直接访问store - 示例:
import { useStore } from 'react-redux';
function DebugComponent() {
const store = useStore();
// 获取当前状态快照
const currentState = store.getState();
// 监听状态变化
useEffect(() => {
const unsubscribe = store.subscribe(() => {
console.log('状态更新:', store.getState());
});
return unsubscribe;
}, [store]);
return <div>调试信息</div>;}
三.React中的组件通信
1.父传子
父组件设置自定义属性,子组件函数中通过形参接收
// 父组件
function Parent() {
const [message, setMessage] = useState('Hello from Parent');
return (
<Child greeting={message} />);}// 子组件function Child({ greeting }) {return <div>{greeting}</div>;}
2.子传父
子组件设置事件的回调函数,父组件通过自定义事件名接收
// 父组件
function Parent() {
const handleChildEvent = (data) => {
console.log('子组件传递的数据:', data);
};
return <Child onEvent={handleChildEvent} />;}// 子组件function Child({ onEvent }) {const sendData = () => {onEvent({ value: '来自子组件的数据' });};return <button onClick={sendData}>发送数据</button>;}
3.跨层级通信
使用Context API创建上下文
// 创建上下文
const FamilyContext = React.createContext();
// 父组件
function Parent() {
return (
<FamilyContext.Provider value={{ surname: 'Smith' }}><Child /></FamilyContext.Provider>);}// 子组件function Child() {const family = useContext(FamilyContext);return <div>姓氏: {family.surname}</div>;}
4.使用ref
// 父组件
function Parent() {
const childRef = useRef();
const callChildMethod = () => {
childRef.current.childMethod();
};
return (
<><Child ref={childRef} /><button onClick={callChildMethod}>调用子组件方法</button></>);}// 子组件(使用 forwardRef)const Child = forwardRef((props, ref) => {useImperativeHandle(ref, () => ({childMethod: () => console.log('子组件方法被调用')}));return <div>子组件</div>;});
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/960741.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!相关文章
详细介绍:C语言——深入解析C语言指针:从基础到实践从入门到精通(二)
pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …
汽车安全核心:TSR技巧需求全解析
汽车安全核心:TSR技巧需求全解析2025-11-09 21:00
tlnshuju
阅读(0)
评论(0) 收藏
举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !impor…
flask:使用flask-migrate迁移数据表
一,安装第三方库
$ pip3 install flask-migrate二,应用
1,在代码中引入安装的库
from flask_migrate import Migrate...migrate = Migrate(app, db)
创建migration目录
$ flask db init
执行migration:在migration目…
docker 搭建 sql 环境
docker 搭建 sql 环境
在网上看了看,原本想直接从 mysql 官网下来,但是看到很多人都是用 docker 搭建的,再想到以后也要会用 docker,最后决定用 docker 来搭建。
下载
在 docker 官网 下载 docker desktop。
下载好…
深入解析:k8s学习(二)——kubernetes整体架构及组件解析
pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …
硬件基础知识和典型应用-4G模组供电设计推荐
硬件基础知识和典型应用-4G模组供电设计推荐<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/LearnHardware" frameborder="0" scrolling="auto" w…
计算机课程在线视频 —— 王道计算机考研 计算机网络
计算机课程在线视频 —— 王道计算机考研 计算机网络地址:
https://www.bilibili.com/video/BV19E411D78Q/本博客是博主个人学习时的一些记录,不保证是为原创,个别文章加入了转载的源地址,还有个别文章是汇总网…
深入解析:归档及压缩、重定向与管道操作和综合使用,find精确查找、find处理查找结果、vim高级使用、vimdiff多文件使用
深入解析:归档及压缩、重定向与管道操作和综合使用,find精确查找、find处理查找结果、vim高级使用、vimdiff多文件使用pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !import…
AI 测试 智能体30节课
目标:
【面试】AI和测试工具的结合应用
【工作】提高工作效率1. AI的初级使用
chat(豆包,元宝,chatgpt)网页对话形式
缺点:
1.数据来源受限于ai服务,不能很好的获取你的数据
2.AI问答功能是有限的,实际工作出了…
BUUCTF-wustctf2020_getshell_2
BUUCTF-wustctf2020_getshell_2BUUCTF-wustctf2020_getshell_2
一、题目来源
BUUCTF-Pwn-wustctf2020_getshell_2二、信息搜集
通过 file 命令查看文件类型:通过 checksec 命令查看文件采用的保护措施:三、反汇编文件…
P14359 [CSP-J 2025] 异或和 / xor(官方数据)
P14359 [CSP-J 2025] 异或和 / xor(官方数据)
错误思路
1. 暴力___概不多说,暴力出奇迹
直接枚举所有可能的子数组,计算每个子数组的异或和并判断是否等于k。但数组长度最大可达510⁵,枚举所有子数组的时间复杂度…
实现AI和BI整合的初步思路和探索
这些年AI火的一塌糊涂,很多行业和传统技术领域都在积极的跟其产生交集。
BI是一个20年前开始火起来的技术,跌跌荡荡这些年,如今虽然不是网红菜,但绝对是企业的必点菜。
AI的出现让很多东西跟人们越来越近,那么AI配…
从CPython底层解析:为何a=10 b=10复用对象,a=[] b=[]新建对象?
从CPython底层解析:为何a=10 b=10复用对象,a=[] b=[]新建对象?
用户的核心疑问本质是:CPython对“不可变对象(如int)”和“可变对象(如list)”采用了完全不同的“对象创建-复用策略”——前者通过“预缓存池”…
Netty线程模型:EventLoop机制与原理解析
目录1. Netty线程模型概述1.1 为什么需要特殊的线程模型?2. EventLoop核心机制2.1 EventLoop基本概念2.1.1. EventLoop执行引擎原理2.1.2. 核心执行逻辑实现2.2. Netty的线程模型实现2.2.1. 主从EventLoopGroup设计2.…
对长度为 n 的数组 arr,调用 `merge_sort(a, 0, n-1)`,在排序过程中,`merge` 函数的递归调用次数大约是多少?
归并排序(Merge Sort) 的标准 基于C++ 实现:对长度为 n 的数组 arr,调用 merge_sort(a, 0, n-1),在排序过程中,merge 函数的递归调用次数大约是多少?✅ 一、代码结构回顾
关键递归函数:
void merge_sort(int a…
解析SP3D VUE和PDMS RVM文件-PlantAssistant
在PlantAssistant中增加视图相关设置选项,如设置是否显示坐标轴、视图方块、三维视图背景,可以设置背景颜色,还可以设置一张图片作为三维视图背景。引言
依托主流工厂设计软件数字化交付数据文件,AVEVA公司PDMS/E3…