React中常用的Hook(useEffect、useRef、useMemo、useNavigate、useParams)

React hook1:useEffect

在编程中,副作用是指函数或表达式在执行过程中对外部环境产生影响的行为。例如:

  • 修改外部变量(如全局变量、DOM、API 请求、设置定时器等)

什么是纯函数?

// 纯函数:输入相同,输出必定相同,不影响外部
function add(a, b) {
  return a + b; 
}
//有副作用的函数:影响外部状态
function updateDOM() {
  document.title = "Changed!"; //副作用:修改DOM
}

React 推崇函数式编程,核心思想是:

  • 组件应该是纯函数(给定相同的props和state,渲染相同的 UI)
  • 副作用应该被隔离,不能直接在渲染过程中执行

React 如何处理副作用?渲染和外部处理相分离。
由于渲染必须是纯的,React 提供了useEffect 让副作用在渲染完成后执行,而不是在渲染期间执行。

useEffect是 React 提供的副作用隔离机制,让不纯的操作(如API请求、DOM修改)不影响组件的纯渲染逻辑,同时提供清理和优化能力。

  1. 保持渲染纯净(在组件渲染到屏幕之后运行)
  2. 避免阻塞渲染
  3. 自动清理副作用(可以返回一个清理函数,在组件卸载时执行)
react jsx title="useEffect基础用法"
import { useEffect } from 'react';

function Example() {
  useEffect(() => {
    console.log('组件首次渲染后执行');
  }, []); // 空依赖数组表示只运行一次

  return <div>组件内容</div>;
}
react jsx title="useEffect引入依赖项监听变化"
function Example({ id }) {
  useEffect(() => {
    console.log('id 变化时执行:', id);
  }, [id]); // 仅在 id 变化时重新执行

  return <div>ID: {id}</div>;
}
react jsx title="useEffect清理副作用"
function Example() {
  useEffect(() => {
    const timer = setInterval(() => {
      console.log('定时器运行中...');
    }, 1000);

    return () => {
      clearInterval(timer); // 组件卸载时清理定时器
    };
  }, []);

  return <div>查看控制台</div>;
}

React hook2:useRef

useRef用于直接操作 DOM或存储可变值(不会触发重新渲染)。

用法1:操作DOM

import { useRef } from 'react';

function InputFocus() {
  const inputRef = useRef(null); // 1. 创建 ref

  const handleClick = () => {
    inputRef.current.focus(); // 3. 通过 .current 操作 DOM
  };

  return (
    <div>
      {/* 2. 绑定 ref 到元素 */}
      <input ref={inputRef} type="text" />
      <button onClick={handleClick}>聚焦输入框</button>
    </div>
  );
}

用法2:存储可变值,不触发重新渲染

import { useRef, useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  const renderCount = useRef(0); // 存储组件渲染次数(不会触发更新)

  renderCount.current += 1; // 修改值(不会导致重新渲染)

  return (
    <div>
      <p>Count: {count}</p>
      <p>组件渲染次数: {renderCount.current}</p>
      <button onClick={() => setCount(count + 1)}>增加</button>
    </div>
  );
}

useRef的底层机制

// 近似实现(React 内部简化逻辑)
function useRef(initialValue) {
  return { current: initialValue }; // 每次都返回同一个对象!
}
  • 存储原理:React 在组件首次渲染时创建这个{ current: … }对象,后续所有渲染都返回同一个对象(引用不变)。
  • 修改current:直接修改current属性不会触发渲染,因为对象本身的引用没变,React 不会检测到变化。

为什么操作 DOM 需要绑定到标签?

<input ref={inputRef} /> 

React 的隐藏逻辑:当ref属性绑定到 DOM 标签时,React 会在渲染结束后自动将 DOM 节点赋值给inputRef.current。

// React 内部类似这样处理
const domNode = document.createElement('input');
inputRef.current = domNode; // 自动填充 DOM 节点

存储变量为何不需要绑定?

const renderCount = useRef(0);
renderCount.current += 1; // 直接修改即可

存储变量时,current只是一个普通属性,你可以自由读写,React 不会干涉它的值。

关键区别总结

场景是否需要绑定到标签current的值来源
操作 DOM需要由 React 自动填充为 DOM 节点
存储可变值不需要由开发者手动赋值/修改

React hook3:useMemo

useMemo用于缓存计算结果,只有当依赖项变化时才重新计算,避免重复渲染时不必要的计算开销。

function UserList({ users, searchTerm }) {
  // 缓存过滤后的用户列表,只有当users或searchTerm变化时才重新过滤
  const filteredUsers = useMemo(() => {
    return users.filter(user => 
      user.name.toLowerCase().includes(searchTerm.toLowerCase())
    );
  }, [users, searchTerm]);

  return (
    <ul>
      {filteredUsers.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

React hook4:useNavigate

**useNavigate 就像一个提供多种导航工具的“工具箱”,可以从中选择需要的功能来完成路由跳转、前进/后退、传递数据等操作。**用“工具箱”类比 useNavigate:

工具箱里的工具对应 useNavigate 的功能
导航地图navigate(‘/path’) —— 直接跳转到指定路径。
橡皮擦navigate(‘/path’, { replace: true }) —— 替换当前路由(擦掉当前记录,不保留历史)。
时间机器按钮navigate(1) 或 navigate(-1) —— 前进或后退到历史记录中的页面。
快递包裹navigate(‘/path’, { state: { data } }) —— 跳转时携带隐藏数据(偷偷塞个包裹给下个页面)。

React hook5:useParams()

useParams从当前 URL 路径中提取参数。

示例代码:

<Route path="/user/:id" element={<UserProfile />} />
import { useParams } from 'react-router-dom';

function UserProfile() {
  // 提取 URL 中的动态参数(比如 :id)
  const params = useParams();
  console.log(params.id); // 访问 /user/123 时,输出 "123"

  return <h1>用户ID: {params.id}</h1>;
}

当用户访问 /user/123 时,useParams() 会提取出 { id: ‘123’ }。

引用\[1\]:在React中,memo是一个高阶组件,用于优化函数组件的性能。它类似于React.PureComponent,通过对内部对象进行浅比较来判断是否重新渲染组件。\[2\]useEffectReact提供的一个Hook函数,用于在函数组件中执行副作用操作。它可以在组件渲染完成后执行一些异步操作,比如发送网络请求、订阅事件等。\[3\]useMemoReact提供的另一个Hook函数,用于在函数组件中进行性能优化。它可以缓存计算结果,避免重复计算,类似于Vue中的computed属性。\[1\]useRefReact提供的一个Hook函数,用于在函数组件中创建一个可变的引用。它可以用来保存组件的状态,或者获取DOM元素的引用。\[1\]useState是React提供的一个Hook函数,用于在函数组件中创建一个可变的状态。它返回一个数组,第一个元素是当前的状态值,第二个元素是更新状态的函数。 所以,react memo用于优化函数组件的性能,useEffect用于执行副作用操作,useMemo用于缓存计算结果,useRef用于创建可变的引用,useState用于创建可变的状态。 #### 引用[.reference_title] - *1* *2* [useMemo,memo,useRef等相关hooks详解](https://blog.csdn.net/weixin_44441196/article/details/117328033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [一文轻松掌握react-hook(useState、useReducer、useEffect、useCallback、useMemouseRef、useContext...)](https://blog.csdn.net/u010074572/article/details/105176653)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值