常用的 hooks 函数

React 的 Hooks 为函数组件引入了之前只能在类组件中使用的功能和生命周期特性。以下是一些常用的 Hooks:

1. useState:

允许函数组件有内部状态。返回一个状态变量和一个设置该状态的函数。

const [count, setCount] = useState(0);

2. useEffect:

用于执行副作用操作,如数据获取、手动更改 DOM 和设置订阅等。它也可以模拟类组件中的生命周期方法。

useEffect(() => {document.title = `Count: ${count}`;
}, [count]);  // 当 count 改变时,这个副作用将重新运行

3. useContext:

允许你使用 context 无需显式地使用 Context.Consumer

useContext 是 React 提供的一个 Hook,它允许你在函数组件中访问当前的 context 值。为了使用 useContext,你首先需要有一个 context。以下是如何创建和使用 context 的步骤:

1. 创建一个 Context

使用 React.createContext 创建一个 context。

const ThemeContext = React.createContext('light'); // 'light' 是默认值

2. 为组件提供 Context 值

使用 Context.Provider 包裹你的组件,为其下层组件提供 context 值。

function App() {return (<ThemeContext.Provider value="dark"><Toolbar /></ThemeContext.Provider>);
}

在上述代码中,Toolbar 组件及其所有子组件都可以访问到 value 为 “dark” 的 context 值。

3. 在函数组件中使用 useContext 读取 Context 值

function Toolbar() {const theme = useContext(ThemeContext);return <div>{theme}</div>;  // 输出 "dark"
}

在上述代码中,Toolbar 组件使用 useContext Hook 来读取 ThemeContext 的当前值。

注意事项:

  • 当 React 渲染使用 useContext 的组件时,它将使用离该组件最近的 <Context.Provider> 的 value 值。如果没有找到 Context.Provider,则使用 React.createContext 时传递的默认值。

  • 记住,每当 Provider 的父组件重新渲染时,Provider 的子组件都将重新渲染,除非你通过使用 memoshouldComponentUpdate 对其进行了优化。

使用 useContext,我们可以更方便地在函数组件中使用 context,避免了过去常常使用的消费者模式(Context.Consumer)。

4. useReducer:

一个替代 useState 的 Hook,适用于复杂的状态逻辑。

const [state, dispatch] = useReducer(reducer, initialArg, init);

useReducer 是 React 提供的一个 Hook,它是一个更为强大和灵活的状态管理机制,尤其适用于有复杂状态逻辑的场景。它的工作方式与 Redux 中的 reducer 很相似。

useReducer 接受两个参数:

  1. reducer:一个函数,它接受当前的 state 和一个 action,然后返回一个新的 state。
  2. initialState:初始状态值。

useReducer 返回一个数组,其中第一个元素是当前的 state,第二个元素是一个 dispatch 函数,你可以使用它来派发 action,以此触发 reducer 函数更新 state。

下面是如何使用 useReducer 的简单示例:

import React, { useReducer } from 'react';// 定义 reducer 函数
function counterReducer(state, action) {switch (action.type) {case 'INCREMENT':return { count: state.count + 1 };case 'DECREMENT':return { count: state.count - 1 };default:return state;}
}function CounterApp() {// 使用 useReducerconst [state, dispatch] = useReducer(counterReducer, { count: 0 });return (<div>Count: {state.count}<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button><button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button></div>);
}export default CounterApp;

在上面的示例中,我们定义了一个简单的 reducer,用于增加或减少计数器的值。然后在 CounterApp 组件中使用了 useReducer,我们可以通过 dispatch 函数派发 'INCREMENT''DECREMENT' 的 action 来更改状态。

这种模式的一个关键好处是它使得组件的逻辑更清晰、更可预测,尤其在你的状态逻辑变得复杂时。此外,与 useState 相比,你可以将业务逻辑从 UI 逻辑中分离出来,这使得你的代码更容易测试和复用。

如果你熟悉 Redux,那么 useReducer 的工作方式会显得非常熟悉,因为它们都遵循相似的模式。但是,与 Redux 不同,useReducer 是完全内置于 React 中的,无需引入额外的库。

5. useCallback:

返回一个记忆化的回调函数。

const increment = useCallback(() => {setCount(c => c + 1);
}, []);

useMemouseCallback 都是 React 提供的 Hooks,旨在优化性能,特别是在有复杂操作或频繁渲染的场景中。它们的核心目的是帮助避免不必要的计算和重新渲染,但它们各自关注的点是不同的。

1. useMemo

useMemo 返回一个memoized 值。你可以将其看作一个记住了之前计算结果的函数。只有在其依赖项数组发生变化时,它才会重新计算这个值。

用途:当你有一个性能开销较大的计算,且这个计算只在某些特定变量改变时才需要重新进行时,可以使用 useMemo

const expensiveCalculation = (data) => {// ... 复杂的计算过程 ...return result;
};function Component(props) {const memoizedResult = useMemo(() => expensiveCalculation(props.data), [props.data]);return <div>{memoizedResult}</div>;
}

2. useCallback

useCallback 返回一个memoized 函数。它接受两个参数:一个函数和一个依赖项数组。它将返回该函数的 memoized 版本,该版本仅在依赖项发生更改时重新创建。

用途:当你传递回调函数给经常重新渲染的子组件或者给 useEffectuseMemo 以及其他 hooks 时,并且你希望避免由于父组件重新渲染导致的不必要的子组件更新或效应的触发,你可以使用 useCallback

function ParentComponent() {const [count, setCount] = useState(0);const increment = useCallback(() => {setCount(count + 1);}, [count]);return <ChildComponent onIncrement={increment} />;
}

在上面的例子中,useCallback 确保只有当 count 发生更改时,increment 函数才会重新创建。这意味着如果 ParentComponent 因为其他原因重新渲染,但 count 没有变化,那么传递给 ChildComponentonIncrement 回调将保持不变。

总结:

  • useMemo:用于优化复杂计算。
  • useCallback:用于优化函数引用,确保函数不会在每次渲染时都被重新创建。

虽然这些 hooks 可以提高性能,但它们并不总是必要的。在没有性能问题的情况下过度优化可能会导致代码更加复杂。建议在确定有性能瓶颈时再使用它们。

6. useMemo:

返回一个记忆化的值。

const computedValue = useMemo(() => expensiveFunction(count), [count]);

7. useRef:

返回一个可变的 ref 对象,它的 .current 属性被初始化为传递的参数。

const inputRef = useRef(null);
// 使用: <input ref={inputRef} />

useRefReact 中的一个 Hook,而 Vue 中的 refs 是 Vue 实例或组件的一个属性。尽管它们都与对 DOM 元素的直接引用有关,但它们在功能和使用方式上有所不同。

  1. React 中的 useRef:

    • 用于访问 DOM 元素或组件的引用
    • 返回一个可变的 ref 对象,其 .current 属性被初始化为传递给 useRef() 的参数(默认为 null)。
    • 常用于访问 DOM 节点,但也可以用作持久性变量的存储,即其值在组件的不同渲染之间保持不变。
    • 当 ref 对象的内容发生变化时,不会触发组件重新渲染。
    function FocusInput() {const inputRef = useRef(null);const handleClick = () => {inputRef.current.focus();};return (<><input ref={inputRef} type="text" /><button onClick={handleClick}>Focus the input</button></>);
    }
    
  2. Vue 中的 refs:

    • 在模板中,可以使用 ref attribute 创建对 DOM 元素或子组件的引用
    • 通过 this.$refs 在组件实例上访问。
    • 通常用于直接操作 DOM 或访问子组件的方法/属性。
    • Vue 3 的 Composition API 中,你还可以在 setup 函数中使用 ref 函数来创建一个响应式引用,但这与 DOM 引用的功能完全不同。
    <template><input ref="myInput" type="text"><button @click="focusInput">Focus the input</button>
    </template><script>
    export default {methods: {focusInput() {this.$refs.myInput.focus();}}
    }
    </script>
    

总结:

  • React 的 useRef 可以用于访问 DOM 元素和持久变量,它返回一个对象,该对象的 .current 属性指向引用的元素。

  • Vue 的 refs 主要用于在模板中创建对 DOM 元素或子组件的引用,并且可以通过 this.$refs 来访问。

这两者在概念上有所重叠,但在使用和功能上有所不同。特别是,Vue 中的 ref 还与 Vue 3 的 Composition API 中的响应性系统有关,这与其在 DOM 引用中的用途完全不同。

8. useLayoutEffect:

useEffect 类似,但它在所有的 DOM 变化后同步触发。

useLayoutEffect(() => {// 读取或修改 DOM 等操作
});

9. useImperativeHandle:

用于自定义暴露给父组件的实例值,当使用 forwardRef 时尤其有用。

10. useDebugValue:

用于在 React DevTools 中显示自定义 Hook 的标签。

除了 React 核心提供的基础 Hooks 外,许多库和开发者还创建了自定义 Hooks 以提供额外的功能和逻辑重用。

Hooks 提供了一种更直观和功能强大的方式来使用函数组件,但在使用它们时应遵循一些规则,如不在循环、条件或嵌套函数中调用 Hooks。

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

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

相关文章

OpenCV(四):Mat支持的运算

目录 1.对两个 Mat 对象按元素进行运算&#xff0c;有加法、减法、乘法和除法等运算。 2.Mat类支持逻辑与、或、非等逻辑运算&#xff0c; 1.对两个 Mat 对象按元素进行运算&#xff0c;有加法、减法、乘法和除法等运算。 加法&#xff1a;Mat Mat&#xff0c;保存到 resul…

【1】openGL glew示例代码分析绘制一个三角形

openGL文档 > docs.gl &#xff0c;可以直接查询函数的定义和使用 #include <iostream> #include <string> #include <GL/glew.h> #include <GLFW/glfw3.h>int main(void) {GLFWwindow* window;/* Initialize the library */if (!glfwInit())retu…

LeetCode_SQL练习(二)

196. 删除重复的电子邮箱 表: Person ---------------------- | Column Name | Type | ---------------------- | id | int | | email | varchar | ----------------------id 是该表的主键列(具有唯一值的列)。 该表的每一行包含一封电子邮件。电子邮件…

vue去掉循环数组中的最后一组的某个样式style/class

vue去掉循环数组中的最后一组的某个样式style/class 需求&#xff1a;要实现这样的排列 现状 发现&#xff0c;最后一个格子并没有跟下面绿色线对齐。 最后发现 是因为 每个格子都给了 margin-right&#xff1a;36px&#xff0c;影响到了最后一个格子 所以要 将最后一个格子的…

Linux:Jupyterhub多用户远程登录安装、使用经验

1、安装 首先&#xff0c;打开官网帮助文档&#xff1a; JupyterHub 官方安装帮助文档 一般安装都是参考官方最新版安装文档。 1.1环境条件 本次安装 JupyterHub的软件环境&#xff1a; 基于 Linux Centos系统&#xff1b;Python 3.9或更高版本&#xff1b;安装 nodejs/n…

CMake rv1109交叉编译环境搭建

安装vmware虚拟机 准备安装包VMware-workstation-full-15.5.1-15018445.exe 下载地址安装 参考资料 在vmware上安装Linux环境 准备安装包ubuntu-18.04.4-desktop-amd64.iso 下载地址安装 参考资料 安装rv1109交叉编译工具链 准备安装包rv1109_toolchain_release.tar.bz2 下…

【深度学习】实验05 构造神经网络示例

文章目录 构造神经网络1. 导入相关库2. 定义一个层3. 构造数据集4. 定义基本模型5. 变量初始化6. 开始训练 构造神经网络 注明&#xff1a;该代码用来训练一个神经网络&#xff0c;网络拟合y x^2-0.5noise&#xff0c;该神经网络的结构是输入层为一个神经元&#xff0c;隐藏层…

高效利用隧道代理实现无阻塞数据采集

在当今信息时代&#xff0c;大量的有价值数据分散于各个网站和平台。然而&#xff0c;许多网站对爬虫程序进行限制或封禁&#xff0c;使得传统方式下的数据采集变得困难重重。本文将向您介绍如何通过使用隧道代理来解决这一问题&#xff0c;并帮助您成为一名高效、顺畅的数据采…

工厂人员作业行为动作识别检测算法

工厂人员作业行为动作识别检测算法通过yolov7python深度学习算法框架模型&#xff0c;工厂人员作业行为动作识别检测算法实时识别并分析现场人员操作动作行为是否符合SOP安全规范流程作业标准&#xff0c;如果不符合则立即抓拍告警提醒。Python是一种由Guido van Rossum开发的通…

【React】React学习:从初级到高级(一)

React学习[一] 1 UI描述1.1 组件的创建与使用1.1.1 创建组件1.1.2 使用组件 1.2 组件的导入与导出1.2.1 根组件文件1.2.2 导出和导入一个组件1.2.3 从同一文件中导出和导入多个组件 1.3 使用JSX书写标签语言1.3.1 JSX:将标签引入JavaScript1.3.2 将HTML转换为JSX1.3.3 高级提示…

Python进阶(1)

Python进阶&#xff08;1&#xff09; 文章目录 Python进阶&#xff08;1&#xff09;一&#xff1a;发送请求&#xff08;GET/POST&#xff09;1.1、方式一&#xff1a;http.client&#xff0c;以https方式为例1.1.1、GET1.1.2、POST 1.2、方式二&#xff1a;requests&#xf…

音视频 ffplay命令播放媒体

播放本地文件 ffplay -window_title "test time" -ss 2 -t 10 -autoexit test.mp4 ffplay buweishui.mp3播放网络流 ffplay -window_title "rtmp stream" rtmp://202.69.69.180:443/webcast/bshdlive-pc强制解码器 mpeg4解码器&#xff1a;ffplay -vco…

Mac安装Dart时,Homebrew报错 Error: Failure while executing

前言&#xff1a; 最近准备开发Flutter项目时&#xff0c;在安装环境时&#xff0c;安装Homebew时遇到了以下报错信息&#xff0c;在这里分享一下。 报错信息&#xff1a; ~ % brew tap dart-lang/dart > Tapping dart-lang/dart Cloning into /opt/homebrew/Library/Tap…

Java-集合框架-List,Set,Map,队列

文章目录 Java集合框架&#xff1a;List&#xff0c;Set&#xff0c;Map&#xff0c;队列Java集合框架是什么&#xff1f;如何使用&#xff1f;ListSetMap队列 什么场景使用&#xff1f;优缺点是什么&#xff1f;ListSetMap队列 Java示例List示例Set示例Map示例队列示例 对比 J…

BMC相关知识

简介 BMC&#xff08;Baseboard Management Controller&#xff09;&#xff0c;基板管理控制器&#xff0c;普通PC没有&#xff0c;服务器产品必备。BMC是一个独立的系统&#xff0c;只要通电即可运行&#xff0c;服务器无需开机&#xff0c;不依赖其它软硬件&#xff0c;如O…

Unity音频基础概念

一、音源与音频侦听器 游戏画面能够被观众看到&#xff0c;是因为有渲染器和摄像机&#xff0c;同样音频能够被听到&#xff0c;也要有声音的发出者与声音的接收者。声音的发出者叫做音源&#xff0c;接收者叫做音频侦听器。Audio Source与Audio Listener都是组件&#xff0c;…

webrtc 的Bundle group 和RTCP-MUX

1&#xff0c;最近调试程序的时候发现抱一个错误 max-bundle configured but session description has no BUNDLE group 最后发现是一个参数设置错误 config.bundle_policy webrtc::PeerConnectionInterface::BundlePolicy::kBundlePolicyMaxBundle; 2&#xff0c;rtcp-mu…

Linux之Shell(一)

Linux之Shell Shell概述Linux提供的Shell解析器bash和sh的关系Centos默认的解析器是bash Shell脚本入门脚本格式第一个脚本脚本常用的执行方式 变量系统预定义变量自定义变量特殊变量$n$#\$*、\$$? 运算符条件判断流程控制(▲)if判断case语句for循环while循环 read读取控制台输…

macos安装zsh

https://www.cnblogs.com/xuLessReigns/p/11005435.html mac下安装autojump brew install autojump 1&#xff0c;安装zsh&#xff0c;执行 sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" 2&#xff0c;将zsh设置…

并发容器11

一 JDK 提供的并发容器总结 JDK 提供的这些容器大部分在 java.util.concurrent 包中。 ConcurrentHashMap: 线程安全的 HashMap CopyOnWriteArrayList: 线程安全的 List&#xff0c;在读多写少的场合性能非常好&#xff0c;远远好于 Vector. ConcurrentLinkedQueue: 高效的并…