大白话React Hooks,新特性怎么用?

server/2025/3/4 22:21:32/

啥是 React Hooks

React Hooks 是 React 16.8 版本引入的新特性,它能让你在不编写 class 的情况下使用 state 以及其他的 React 特性。就好比以前你盖房子得用一种特定的建筑方式(class 组件),现在有了新工具(Hooks),不用那种特定方式也能盖出很棒的房子。它可以让你的代码更简洁、更易复用。

常用的 React Hooks 及其使用方法

1. useState
  • 作用:让你在函数组件里使用 state,就像给函数组件装上了能存储数据的小盒子。
  • 使用方法:它接收一个初始值作为参数,返回一个数组,数组的第一个元素是当前的 state 值,第二个元素是一个函数,用于更新这个 state
import React, { useState } from 'react';function Counter() {// 定义一个名为 count 的 state,初始值为 0// useState 返回一个数组,第一个元素是 count 的值,第二个元素是更新 count 的函数 setCountconst [count, setCount] = useState(0);return (<div>{/* 显示 count 的值 */}<p>你点击了 {count} 次</p>{/* 点击按钮时调用 setCount 函数,将 count 的值加 1 */}<button onClick={() => setCount(count + 1)}>点击我</button></div>);
}export default Counter;
2. useEffect
  • 作用:可以让你在函数组件里执行副作用操作,比如数据获取、订阅、手动修改 DOM 等。就像在房子盖好后,你可以用它来做一些额外的装饰或者布置。
  • 使用方法:它接收一个回调函数作为第一个参数,这个回调函数会在组件渲染后执行。第二个参数是一个可选的数组,用于指定哪些值发生变化时才执行这个回调函数。如果不传第二个参数,回调函数会在每次组件渲染后都执行;如果传一个空数组,回调函数只会在组件第一次渲染后执行。
import React, { useState, useEffect } from 'react';function DataFetcher() {// 定义一个名为 data 的 state,初始值为 nullconst [data, setData] = useState(null);// 使用 useEffect 进行数据获取useEffect(() => {// 模拟一个异步的数据获取操作const fetchData = async () => {const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');const result = await response.json();// 将获取到的数据更新到 data state 中setData(result);};// 调用数据获取函数fetchData();// 可以返回一个清理函数,用于在组件卸载时执行一些清理操作,比如取消订阅等return () => {console.log('组件卸载了');};}, []); // 传入空数组,表示这个 useEffect 只在组件第一次渲染后执行return (<div>{data? (// 如果 data 不为 null,显示数据的标题<p>{data.title}</p>) : (// 如果 data 为 null,显示加载中<p>加载中...</p>)}</div>);
}export default DataFetcher;
3. useContext
  • 作用:让你在函数组件里使用 React 的上下文(Context),可以方便地在组件树中传递数据,而不用一层一层地通过 props 传递。就像有一个公共的仓库,所有组件都能去里面拿东西。
  • 使用方法:它接收一个 Context 对象作为参数,返回这个 Context 当前的值。
import React, { createContext, useContext } from 'react';// 创建一个 Context 对象,初始值为 '默认值'
const MyContext = createContext('默认值');function ChildComponent() {// 使用 useContext 获取 MyContext 的值const value = useContext(MyContext);return (<div>{/* 显示从上下文获取的值 */}<p>从上下文获取的值: {value}</p></div>);
}function ParentComponent() {return (// 使用 MyContext.Provider 提供一个新的值 '新的值'<MyContext.Provider value="新的值"><ChildComponent /></MyContext.Provider>);
}export default ParentComponent;
4. useReducer
  • 作用:是 useState 的替代方案,适用于复杂的 state 逻辑,比如多个子值或者下一个 state 依赖于之前的 state。就像一个更强大的 state 管理工具。
  • 使用方法:它接收一个 reducer 函数和一个初始 state 作为参数,返回一个数组,数组的第一个元素是当前的 state 值,第二个元素是一个 dispatch 函数,用于触发 reducer 中的操作。
import React, { useReducer } from 'react';// 定义一个 reducer 函数,接收当前 state 和一个 action,返回新的 state
const reducer = (state, action) => {switch (action.type) {case 'increment':return { count: state.count + 1 };case 'decrement':return { count: state.count - 1 };default:return state;}
};function CounterWithReducer() {// 使用 useReducer 定义 state 和 dispatch 函数const [state, dispatch] = useReducer(reducer, { count: 0 });return (<div>{/* 显示 count 的值 */}<p>你点击了 {state.count} 次</p>{/* 点击按钮时调用 dispatch 函数,触发 increment 操作 */}<button onClick={() => dispatch({ type: 'increment' })}>增加</button>{/* 点击按钮时调用 dispatch 函数,触发 decrement 操作 */}<button onClick={() => dispatch({ type: 'decrement' })}>减少</button></div>);
}export default CounterWithReducer;

通过这些 Hooks,你可以在函数组件里实现很多原本 class 组件才能实现的功能,让代码更加简洁和易于维护。

如何优化使用React Hooks的代码性能?

咱来唠唠怎么优化使用 React Hooks 的代码性能,下面从几个方面详细说说:

别让组件瞎渲染

  • 给组件加个“检查器”React.memo 就像是个检查官,能帮函数组件检查传入的 props 有没有变化。要是 props 和上次一样,它就不让组件重新渲染,省了不少力气。比如说你有个组件专门显示用户信息,只要用户信息的 props 没改,这个组件就不用重新画一遍,这样性能就提升了。代码大概这么写:
import React from'react';
// 用 React.memo 包裹组件
const UserInfo = React.memo(({ name, age }) => {return (<div><p>姓名: {name}</p><p>年龄: {age}</p></div>);
});
export default UserInfo;
  • 缓存计算结果useMemo 就像个小仓库,能把一些计算结果存起来。要是依赖的东西没变化,就直接从仓库里拿结果,不用重新算一遍。比如你有个组件要对一个数组里的数字做复杂计算,每次数组没变就不用重新算,直接用之前算好的结果就行。代码示例如下:
import React, { useMemo } from'react';
function CalculateList({ numbers }) {const calculatedResult = useMemo(() => {// 假设这里是复杂的计算逻辑return numbers.map(num => num * 2);}, [numbers]);return (<ul>{calculatedResult.map(result => (<li key={result}>{result}</li>))}</ul>);
}
export default CalculateList;

用好 useEffect

  • 精准设置依赖项useEffect 就像个小跟班,会在组件渲染后做一些额外的事儿。但你得告诉它什么时候该干活,这就靠依赖项数组。要是依赖项数组是空的,它就只在组件刚创建和销毁的时候干活;要是数组里有东西,这些东西变了它才会重新干活。比如说你有个组件要在 count 变化时发个网络请求,那就把 count 放进依赖项数组里。代码如下:
import React, { useState, useEffect } from'react';
function MyComponent() {const [count, setCount] = useState(0);useEffect(() => {// 只有 count 变化时才会发请求console.log(`Count 变成了 ${count}`);// 这里可以放网络请求的代码}, [count]);return (<div><button onClick={() => setCount(count + 1)}>加 1</button></div>);
}
export default MyComponent;
  • 别在 useEffect 里瞎更新:要是在 useEffect 里做了会让组件重新渲染的事儿,得确保这事儿是必要的,不然就会陷入无限循环,像个疯了的小陀螺。你可以用 useRef 来保存一些临时状态,避免不必要的更新。

优化事件处理

  • 缓存事件处理函数useCallback 就像个函数小管家,能把事件处理函数存起来。每次组件渲染时,只要依赖项没变,它就还是用原来的函数,不用重新创建一个新的。比如你有个按钮的点击事件处理函数,用 useCallback 缓存后,性能会更好。代码如下:
import React, { useState, useCallback } from'react';
function MyButton() {const [count, setCount] = useState(0);const handleClick = useCallback(() => {setCount(count + 1);}, [count]);return <button onClick={handleClick}>点击我</button>;
}
export default MyButton;

其他小窍门

  • 把大组件拆成小零件:要是一个组件功能太多、太复杂,就把它拆成好几个小的、功能单一的组件。这样每个小组件好维护,也容易复用,性能自然就上去了。
  • 别在循环里乱用 Hooks:React 规定 Hooks 只能在组件最外面或者自定义 Hooks 里面用,别在循环、判断或者嵌套函数里用,不然会出性能问题,还不好找错。
  • 懒加载组件:有些组件不常用或者加载起来特别慢,就用 React 的懒加载功能。等需要用这个组件的时候再去加载它,这样页面一开始加载得就快多了。

http://www.ppmy.cn/server/172436.html

相关文章

强化学习无痛上手笔记第1课

文章目录 Markov Decision ProcessDefinitionRelated Concepts Policy for MDP AgentDefinitionJudgement for PolicyValue FunctionsTD formula for value functionsRelation of V and QPolicy CriterionPolicy Improvement TheoremOptimal PolicyReinforcement Learning Fund…

2024年国赛高教杯数学建模A题板凳龙闹元宵解题全过程文档及程序

2024年国赛高教杯数学建模 A题 板凳龙闹元宵 原题再现 “板凳龙”&#xff0c;又称“盘龙”&#xff0c;是浙闽地区的传统地方民俗文化活动。人们将少则几十条&#xff0c;多则上百条的板凳首尾相连&#xff0c;形成蜿蜒曲折的板凳龙。盘龙时&#xff0c;龙头在前领头&#x…

C++初阶—list类

第一章&#xff1a;list的介绍及使用 1.1 list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指…

常见的正则匹配规则

目录 1&#xff0c;匹配数字2&#xff0c;匹配字母3&#xff0c;匹配字母和数字4&#xff0c;匹配邮箱地址5&#xff0c;匹配URL6&#xff0c;匹配身份证号7&#xff0c;匹配手机号8&#xff0c;匹配日期9&#xff0c;匹配IP地址10&#xff0c;匹配密码强度11&#xff0c;匹配空…

bc命令学习9 获取bc命令的源码并编译

本文介绍如何获取bc命令的源码并编译,这个对于初学linux还是有点难的,主要坑比较多。下面主要介绍windows下使用wsl环境进行编译 1 初始化工作 创建一个文件夹,我选择创建一个C:\run\linux,这个可以自己选择.然后启动在该文件夹下面启动wsl ,首先获取bc文件的相关信息,可以看…

Lua | 每日一练 (5)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 Lua | 每日一练 (5)题目参考答案浅拷贝深拷贝使用场景…

蓝桥与力扣刷题(蓝桥 k倍区间)

题目&#xff1a;给定一个长度为 N 的数列&#xff0c;A1,A2,⋯AN​&#xff0c;如果其中一段连续的子序列 Ai,Ai1,⋯Aj( i≤j ) 之和是 K 的倍数&#xff0c;我们就称这个区间[i,j] 是 K 倍区间。 你能求出数列中总共有多少个 K 倍区间吗&#xff1f; 输入描述 第一行包含两…

【Elasticsearch】集群配置性能优化

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程,高并发设计,Springboot和微服务,熟悉Linux,ESXI虚拟化以及云原生Docker和K8s,热衷于探…