React中Hooks--useEffect | useState | useCallback | useMemo

一、useEffect

useEffect 是 React 提供的一个 Hook,用于在函数组件中执行副作用操作(side effects),例如数据获取、订阅、或手动更改 DOM 等。useEffect 相当于类组件中的生命周期方法,但是它提供了更多的灵活性。

基本用法

useEffect 接受两个参数:

  1. Effect 函数:这是一个包含副作用操作的函数,它将在组件渲染到屏幕后执行。
  2. 依赖项数组:这个数组定义了 effect 函数依赖的组件状态或属性。如果数组中的值发生变化,effect 函数将重新执行。
示例:
import React, { useState, useEffect } from 'react';function Example() {const [count, setCount] = useState(0);// 基本的 useEffect:类似于 componentDidMount 和 componentDidUpdateuseEffect(() => {console.log('count is updated:', count);// 执行副作用操作...}, [count]); // 依赖项数组包含 count,当 count 变化时 effect 重新执行return (<div><p>You clicked {count} times</p><button onClick={() => setCount(count + 1)}>Click me</button></div>);
}

清理副作用

useEffect 可以返回一个函数,这个函数在组件卸载或重新渲染前执行,用于清理副作用。

示例:
import React, { useState, useEffect } from 'react';function Example() {const [count, setCount] = useState(0);// 基本的 useEffect:类似于 componentDidMount 和 componentDidUpdateuseEffect(() => {console.log('count is updated:', count);// 执行副作用操作...}, [count]); // 依赖项数组包含 count,当 count 变化时 effect 重新执行return (<div><p>You clicked {count} times</p><button onClick={() => setCount(count + 1)}>Click me</button></div>);
}

仅在组件挂载时执行

如果你希望副作用仅在组件挂载时执行一次,你可以传递一个空数组 [] 作为 useEffect 的第二个参数。

示例:
import React, { useState, useEffect } from 'react';function Example() {const [count, setCount] = useState(0);// 基本的 useEffect:类似于 componentDidMount 和 componentDidUpdateuseEffect(() => {console.log('count is updated:', count);// 执行副作用操作...}, [count]); // 依赖项数组包含 count,当 count 变化时 effect 重新执行return (<div><p>You clicked {count} times</p><button onClick={() => setCount(count + 1)}>Click me</button></div>);
}

模拟 componentDidUpdate

如果你需要在组件更新时执行副作用,但不在挂载时执行,你可以使用非空的依赖项数组。

示例:
useEffect(() => {// 仅在特定 props 更新时执行console.log('特定 props 更新了');
}, [specificProp]); // 依赖项数组包含 specificProp

模拟 componentWillUnmount

如果你需要在组件卸载时执行清理操作,可以返回一个函数。

示例:
useEffect(() => {function handleStorageChange() {// 处理存储变化}window.addEventListener('storage', handleStorageChange);// 组件卸载时的清理操作return () => {window.removeEventListener('storage', handleStorageChange);};
}, []); // 空依赖项数组,仅在组件挂载时执行一次

总结

useEffect 提供了一种灵活的方式来处理组件的副作用操作,它使得函数组件能够执行原本需要在类组件的生命周期方法中执行的操作。通过依赖项数组,useEffect 能够智能地决定何时执行副作用函数,从而避免不必要的副作用执行和潜在的性能问题。

二、useState

useState 是 React 的一个 Hook,它允许你在函数组件中添加 React 状态。这个 Hook 是 React 16.8+ 版本引入的,并且成为了在函数组件中处理状态的首选方式。

基本用法

useState 接受一个参数:初始状态(可以是任何类型,包括对象、数组、基本类型等)。它返回一个数组,包含两个元素:

  1. 当前状态:组件的状态值。
  2. 更新状态的函数:允许你更新状态,这个函数调用时可以传入一个新的状态值,React 将负责重新渲染组件。
示例:
import React, { useState } from 'react';function Counter() {// 初始化状态为 0const [count, setCount] = useState(0);return (<div><p>Count: {count}</p><button onClick={() => setCount(count + 1)}>Increment</button><button onClick={() => setCount(count - 1)}>Decrement</button></div>);
}

在这个例子中,count 是当前的状态值,setCount 是更新这个状态的函数。

使用函数更新状态

你可以在调用更新函数时传递一个函数,这个函数接收上一个状态作为参数,并返回新的状态。这在你需要基于前一个状态来计算新状态时非常有用。

示例:
function Counter() {const [count, setCount] = useState(0);const incrementCount = () => {setCount((prevCount) => prevCount + 1);};return (<div><p>Count: {count}</p><button onClick={incrementCount}>Increment</button></div>);
}

多个状态变量

如果你需要在组件中使用多个状态变量,你可以调用 useState 多次来分别创建它们。

示例:
function Form() {const [username, setUsername] = useState('');const [password, setPassword] = useState('');// 其他逻辑...return (<form><inputtype="text"value={username}onChange={(e) => setUsername(e.target.value)}/><inputtype="password"value={password}onChange={(e) => setPassword(e.target.value)}/>{/* 其他表单元素 */}</form>);
}

总结

useState 是函数组件中处理状态的核心 Hook,它使得在函数组件中使用状态变得简单直接。通过 useState,你可以轻松地添加、更新和维护组件的状态,同时享受 React 的响应式更新和性能优化。

三、useCallback

useCallback 是 React 提供的一个 Hook,它用于记忆化(memoization)函数。这意味着 React 会返回同一个函数引用,只要依赖项数组中的值没有变化。这在性能优化中非常有用,特别是当你希望避免在每次渲染时创建新的函数实例,或者在子组件中使用这些函数时。

基本用法

import React, { useCallback } from 'react';function MyComponent() {// 定义一个函数const myFunction = (arg) => {console.log(arg);};// 使用 useCallback 记忆化该函数const memoizedFunction = useCallback(myFunction, []); // 空依赖数组// memoizedFunction 现在是一个记忆化的函数// 只要组件没有重新渲染,它就会保持相同的引用return <div onClick={() => memoizedFunction('Hello!')}>Click me!</div>;
}

useCallback 是 React 提供的一个 Hook,它用于记忆化(memoization)函数。这意味着 React 会返回同一个函数引用,只要依赖项数组中的值没有变化。这在性能优化中非常有用,特别是当你希望避免在每次渲染时创建新的函数实例,或者在子组件中使用这些函数时。

基本用法

 

import React, { useCallback } from 'react'; function MyComponent() { // 定义一个函数 const myFunction = (arg) => { console.log(arg); }; // 使用 useCallback 记忆化该函数 const memoizedFunction = useCallback(myFunction, []); // 空依赖数组 // memoizedFunction 现在是一个记忆化的函数 // 只要组件没有重新渲染,它就会保持相同的引用 return <div onClick={() => memoizedFunction('Hello!')}>Click me!</div>; }

参数说明

  • 第一个参数:要记忆化的函数。
  • 第二个参数:依赖项数组。只有当这个数组中的值发生变化时,React 才会重新创建函数。

使用场景

  1. 避免子组件的不必要渲染: 当你将回调函数传递给子组件,并且子组件在渲染时使用了这个函数,如果父组件每次渲染都创建一个新的函数实例,子组件可能会因为引用变化而重新渲染。

  2. 优化性能: 通过记忆化,可以减少不必要的计算和 DOM 操作,提高应用性能。

  3. useMemo 结合使用: 有时候,你不仅需要记忆化函数,还需要记忆化计算结果。useCallback 可以与 useMemo 一起使用来优化性能。

  4. 在事件处理器中使用: 事件处理器函数经常作为属性传递给 DOM 元素,使用 useCallback 可以避免因函数引用变化导致的重复渲染。

  5. useEffect 或其他 Hook 中使用: 当回调函数用于 useEffect 或其他 Hook 时,使用 useCallback 可以确保这些 Hook 在不必要的情况下不会运行。

注意事项

  • 当使用 useCallback 时,确保依赖项数组包含了所有外部依赖,以避免记忆化失败。
  • 如果依赖项数组为空([]),那么回调函数只会在组件挂载时创建一次。
  • 记忆化的函数不应该有任何副作用,因为它们可能会在组件的整个生命周期内保持不变。

通过使用 useCallback,你可以更好地控制 React 组件的性能和渲染行为。

四、useMemo

useMemo 用于记忆化复杂计算的结果,确保只有在依赖项变化时才重新计算,从而避免不必要的性能开销。

基本用法:

const memoizedValue = useMemo(() => {// 这里是你的计算逻辑return someExpensiveComputation(a, b);
}, [a, b]); // 依赖项数组
  • 第一个参数:一个函数,它返回你想要记忆化的值。这个函数只有在依赖项变化时才会执行。
  • 第二个参数:依赖项数组。只有当这个数组中的某个元素发生变化时,函数才会重新执行,并且返回的新值会替换缓存的值。

特点

  • useMemo 仅在其依赖项变化时才重新计算。如果依赖项没有变化,它将返回缓存的值,而不是重新执行函数。
  • 它非常适合用于性能优化,尤其是在处理复杂的计算或大数据集时。

使用场景

  1. 避免重复的计算:当某个计算结果在多次渲染中保持不变时,使用 useMemo 可以避免不必要的计算。

  2. 优化渲染性能:通过缓存结果,减少渲染期间的计算量,提高渲染性能。

  3. 与依赖项解耦:当计算结果与组件的多个属性或状态相关联时,useMemo 可以确保只在相关依赖项变化时重新计算。

示例

假设你有一个组件,它根据传入的数值进行一些复杂的计算:

import React, { useMemo } from 'react';function MyComponent({ a, b }) {// 使用 useMemo 来记忆化计算结果const result = useMemo(() => {// 假设这是一个昂贵的计算const expensiveComputation = (x, y) => {// ...进行一些计算...return x * y;};return expensiveComputation(a, b);}, [a, b]); // 当 a 或 b 变化时,重新计算return (<div><p>The result is: {result}</p></div>);
}

在这个示例中,result 只有在 ab 发生变化时才会重新计算。如果没有变化,它将返回缓存的值,从而避免重复的计算。

注意事项

  • 确保依赖项数组完整,否则可能会导致错误的缓存结果。
  • 不要将 useMemo 用于包含副作用的计算,它只适用于纯计算。
  • 使用 useMemo 可以提高性能,但也要小心不要过度使用,因为它可能会增加内存使用。

通过合理使用 useMemo,你可以有效地优化 React 组件的性能,减少不必要的计算和渲染。

useCallback 和 useMemo的区别:

  1. 记忆化内容

    • useCallback 记忆化函数。
    • useMemo 记忆化计算结果。
  2. 返回值

    • useCallback 返回一个函数。
    • useMemo 返回计算结果。
  3. 使用时机

    • useCallback 通常用于事件处理器或传递给子组件的函数。
    • useMemo 通常用于优化性能,避免在渲染期间进行昂贵的计算。
  4. 副作用

    • useCallback 的函数不应该包含副作用。
    • useMemo 的函数可以执行计算,但不应该包含副作用。
  5. 依赖项变化时的行为

    • 当依赖项变化时,useCallback 会重新创建函数。
    • 当依赖项变化时,useMemo 会重新执行计算函数。

示例

import React, { useMemo, useCallback } from 'react';function MyComponent(a, b) {// 记忆化回调函数,避免子组件不必要渲染const handleClick = useCallback(() => {console.log('Clicked with', a, b);}, [a, b]);// 记忆化计算结果,避免重复计算const computedValue = useMemo(() => {return a * b;}, [a, b]);return (<div><button onClick={handleClick}>Click me</button><p>Computed Value: {computedValue}</p></div>);
}

一边学习一边更新~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/27732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

照明灯具哪个品牌好,一文详细带你了解照明灯具种类有哪些

在孩子学习过程中&#xff0c;有一样物品的重要性不容忽视&#xff0c;那就是一盏提供舒适光源的照明灯具。那么照明灯具哪个品牌好&#xff1f;面对不断增加的学业负担&#xff0c;孩子们经常需要在夜晚借助台灯的光亮进行学习&#xff0c;这已经成为了家庭生活中普遍的情景。…

Vue34-销毁流程

一、销毁流程预览 二、vm.$destroy()函数的调用&#xff0c;开始销毁流程 一个应用只有一个vm&#xff0c;但是一个vm会管理一堆组件实例对象&#xff08;和vm很像&#xff1a;微型的vm&#xff09;。 销毁流程中解绑的事件监听器&#xff0c;是自定义事件&#xff0c;不是原…

uni app 自定义 带popup弹窗的input组件

工作需要。自定义了个带popup弹窗的input组件。此组件满足个人需求&#xff0c;不喜勿喷。应该可以看明白怎么回事&#xff0c;也能自己改改&#xff0c;所以就不要联系了&#xff0c;点赞收藏就好 <template><view class"dialog_main"><input v-mod…

Mantis-ML 2.0识别基因-疾病关联,Beam Pro实现无需后期的AR视频拍摄与三维空间应用

一支烟花官网&#xff1a; https://agifun.love 智源社区 Sci. Adv. | 治疗性遗传靶点的全表型识别 DRUGAI今天为大家介绍的是来自Dimitrios Vitsios团队的一篇论文。人类基因组数据集的持续扩展推动了治疗靶点的识别&#xff0c;然而&#xff0c;从基因注释中提取基因-疾病…

这份简历让一位程序员在谷歌获得30万美元

大家好&#xff0c;我是弗雷。每次都在让大家尝试走出职场&#xff0c;但今天我们却选择再次走进职场。 作为曾经的职场人&#xff0c;我深深明白简历的敲门砖作用&#xff0c;制作一份优质的简历至关重要。 你所见过的最优秀的简历是什么样子&#xff1f; 或者你想象中最优秀…

商业银行和投资银行有什么区别?

商业银行和投资银行在业务性质、服务对象、风险管理等方面有显著区别。以下是两者的主要区别及相关的历史背景&#xff1a; 中文版 商业银行&#xff08;Commercial Bank&#xff09; 主要功能 存款业务&#xff1a;吸收公众存款&#xff0c;并为存款人提供安全的存款服务。…

Superset二次开发之调研篇 v3.0 VS v4.0

功能变化(v3.0 与 v4.0)参考releases 在 Superset 官方版本升级过程中,对源码进行了大量修改。这不仅解决了许多安全问题,减少了漏洞,还显著增强了系统的稳定性和安全性。同时,废弃了旧的可视化图表和许多不再使用的功能,也引入了众多新的用户体验和改进之处。关注版本…

vscode创建一个jest测试框架的项目

在Visual Studio Code (VSCode) 中创建一个用于单独测试JavaScript方法的项目相对简单。以下是一步步指导&#xff1a; ### 1. 创建项目文件夹 首先&#xff0c;在你的电脑上选择一个合适的位置创建一个新的文件夹&#xff0c;这将作为你的项目目录。 ### 2. 打开VSCode并设置项…

chatgpt的命令词

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

TypeScript 学习笔记(二十二):TypeScript 与微服务架构的结合使用

TypeScript 学习笔记&#xff08;二十二&#xff09;&#xff1a;TypeScript 与微服务架构的结合使用 1. 引言 在前几篇学习笔记中&#xff0c;我们探讨了 TypeScript 的基础知识、前后端框架的结合应用、性能优化、前端架构设计、工具和生态系统&#xff0c;以及 TypeScript…

MYSQL execute command denied to user ‘‘@‘%‘ for routine

有时候 某个MYSQL用户无法执行某个函数. 有时候你赋了EXECUTE *.* 权限也不行 grant EXECUTE on DATA.* to platfrom%; 还真麻烦! show grants for platfrom%; 先看下有啥权限? 查找一翻 正确赋函数执行权限是这样的 grant EXECUTE on function data.RAND_STRING to p…

ABBYY Finereader 15软件下载及安装教程

ABBYY FineReader 是一款功能强大的 OCR&#xff08;Optical Character Recognition&#xff09;软件&#xff0c;可以将扫描的文档转换为可编辑的文本文件。它不仅可以识别文本&#xff0c;还可以识别表格、图像和布局&#xff0c;使得文档的转换更加准确和方便。 安 装 包 获…

Opus从入门到精通(五)OggOpus封装器全解析

Opus从入门到精通(五)OggOpus封装器全解析 为什么要封装 前面Opus从入门到精通(四)Opus解码程序实现提到如果不封装会有两个问题: 无法从文件本身获取音频的元数据(采样率,声道数,码率等)缺少帧分隔标识,无法从连续的文件流中分隔帧(尤其是vbr情况) 针对上面的问题我们可以…

算法day31

第一题 542. 01 矩阵 本题本来求解的是每一个1到0的最短距离并返回到矩阵之中&#xff1b; 我们采用正难则反的思路&#xff0c;将其化解为每一个0到每一个1的最短距离&#xff0c;并通过矩阵来返回&#xff1b; 解法&#xff1a;多源bfs正难则反 步骤一&#xff1a; 定义一个…

如何通过ChatGPT赚取11000美元:我的成功故事

作者&#xff1a;Skylar Johnson 随着像ChatGPT这样的AI语言模型的出现&#xff0c;赚取金钱和使用先进技术的机会变得越来越容易获得。在这篇文章中&#xff0c;我将分享我个人如何利用ChatGPT赚取11000美元的成功故事。跟随我的旅程可以给你提供洞见和灵感&#xff0c;去探索…

换卡槽=停机?新手机号使用指南!

刚办理的手机号莫名其妙的就被停用了&#xff1f;这到底是怎么回事&#xff1f;这篇文章快来学习一下吧。 ​ 先说一下&#xff0c;你的手机为什么被停机&#xff1f; 现在运营商对于手机卡的使用有着非常严格的要求&#xff0c;尤其是刚办理的新号码&#xff0c;更是“严上加…

Docker镜像构建:Ubuntu18.04+python3.10

1、编写 Dockerfile # 使用Ubuntu 18.04作为基础镜像 FROM ubuntu:18.04RUN apt-get update && apt-get install -y \build-essential \curl \zlib1g-dev \libssl-dev \&& rm -rf /var/lib/apt/lists/*ENV PYTHON_VERSION3.10.8RUN curl -O https://www.pytho…

el-table表格与分页器实现跨页连续计数

直接看代码,只需要让页数pageNum减去1后去乘以要展示的数量pageSize再加上当前索引值加1就可以 <el-table :data"tableData" stripe class"table" ><el-table-column label"序号" type"index" width"100"><t…

【2024算力大会分会 | SPIE独立出版 | 往届均已完成EI检索】2024云计算、性能计算与深度学习国际学术会议(CCPCDL 2024)

【2024算力大会分会 | SPIE出版】 2024云计算、性能计算与深度学习国际学术会议(CCPCDL 2024) 2024 International conference on Cloud Computing, Performance Computing and Deep Learning *CCPCDL往届均已完成EI检索&#xff0c;最快会后4个半月完成&#xff01; 一、…

有关侧信道攻击,你都知道哪些? 你们的TEE/TA可以防侧信道攻击吗?

侧信道攻击(Side-Channel Attacks,SCA)是一种利用物理信息泄露来推断计算机系统内秘密数据的攻击方法。它与传统的攻击方法不同,不直接依赖于算法的漏洞,而是通过分析系统在处理数据时的物理特性(如功耗、电磁辐射、时间延迟等)来推断机密信息。 常见的侧信道攻击类型 …