React18学习笔记(五) 【总结】常用的React Hooks函数,常用React-Redux Hooks函数和React中的组件通信

文章目录

      • [一.常用React Hooks函数](#一.常用React Hooks函数)
        • [1.useState - 状态管理](#1.useState - 状态管理)
        • [2.useEffect - 副作用处理](#2.useEffect - 副作用处理)
        • [3.useRef - 引用DOM或存储可变值](#3.useRef - 引用DOM或存储可变值)
        • [4.useMemo - 记忆化计算结果](#4.useMemo - 记忆化计算结果)
        • [5.useContext - 访问上下文](#5.useContext - 访问上下文)
        • [6.useCallback - 记忆化函数](#6.useCallback - 记忆化函数)
        • [7.自定义React Hooks函数](#7.自定义React Hooks函数)
      • [二.常用React-Redux Hooks函数](#二.常用React-Redux Hooks函数)
        • [1.useSelector - 访问Redux Store的状态](#1.useSelector - 访问Redux Store的状态)
        • [2.useDispatch - 分发Action](#2.useDispatch - 分发Action)
        • [3.useStore - 访问Store示例](#3.useStore - 访问Store示例)
      • 三.React中的组件通信

一.常用React Hooks函数

1.useState - 状态管理
  • 作用:用于在函数组件中添加状态管理,创建状态变量
  • 特点:状态变量只能由其状态更新函数来更新其值,状态更新时会触发组件重新渲染
  • 示例:
javascript 复制代码
import {useState} from "react"
const [isVisible,setIsVisible] = useState(false)
const handleClick=()=>{
	setIsVisible(!isVisible)
}
2.useEffect - 副作用处理

作用:处理组件中的副作用(数据获取,订阅,手动操作DOM等)

参数:副作用函数和依赖项

特点:在组件渲染后执行,通过依赖数组控制执行的时机

使用场景:API请求、事件监听、定时器、操作DOM

示例:

javascript 复制代码
	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框的焦点
javascript 复制代码
  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">
  <input 
    type="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)
  • 特点:依赖不变时返回缓存值,减少不必要的计算开销
  • 注意事项:不要用于有副作用的操作并确保计算函数是纯函数
  • 示例:
javascript 复制代码
  //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层层传递
  • 注意事项:组件会在上下文值变化时重新渲染,当使用多个上下文时嵌套顺序会影响值获取
  • 常用场景:主体切换、用户认证、多语言支持
  • 示例:
javascript 复制代码
// 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、事件处理函数
  • 示例:
javascript 复制代码
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函数
javascript 复制代码
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 中返回新的引用类型对象
  • 示例:引入后台消费数据
javascript 复制代码
/*省流:只看使用部分*/
//使用----组件内(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 storedispatch函数引用
  • 特点:返回的dispatch引用时稳定的,不会随着渲染改变
  • 最佳实践:把dispatch逻辑封装在回调函数中
  • 示例:
javascript 复制代码
//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
  • 示例:
javascript 复制代码
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.父传子

父组件设置自定义属性,子组件函数中通过形参接收

javascript 复制代码
// 父组件
function Parent() {
  const [message, setMessage] = useState('Hello from Parent');
  
  return (
    <Child greeting={message} />
  );
}

// 子组件
function Child({ greeting }) {
  return <div>{greeting}</div>;
}
2.子传父

子组件设置事件的回调函数,父组件通过自定义事件名接收

javascript 复制代码
// 父组件
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创建上下文

javascript 复制代码
// 创建上下文
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
javascript 复制代码
// 父组件
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>;
});
相关推荐
LaughingZhu9 小时前
智能体经典范式构建:ReAct、Plan-and-Solve 与 Reflection
前端·react.js·前端框架
飞天狗10 小时前
长列表滚动卡顿怎么破:虚拟列表选型 + react-virtuoso 实战调优指南
react.js·性能优化
binbin_5213 小时前
React 井字棋教程:用一个小游戏理解组件和状态
前端·react.js·前端框架
张元清14 小时前
React useObjectUrl Hook:预览文件与 Blob,不留内存泄漏(2026)
javascript·react.js
真的想不出名儿18 小时前
Md编辑器整合-react
前端·react.js·编辑器
牛仔只喝牛奶1 天前
多端跨端技术选型:小程序 + H5 + App 的两栈拆分落地
react native·react.js
wear工程师1 天前
setState 到底是不是异步的?这题从 React 16 问到 18,标准答案早就变了
react.js·面试
wanghowie2 天前
LangGraph4j 落地(二)— ReAct 多步工具与 trace 扩展
前端·react.js·前端框架
csj502 天前
前端基础之《React(11)—state声明式》
前端·react.js
张元清2 天前
React useLocalStorage Hook:SSR 安全的持久化状态(2026)
javascript·react.js