React Hooks 是函数组件的“魔法棒”,而自定义 Hooks 则是你亲手打造的“专属魔法”。通过封装复用逻辑,自定义 Hooks 能让代码更简洁、更优雅。今天,我将通过三个有趣的 Demo —— 切换状态、数据请求 和 本地存储,带你从零到一掌握自定义 Hooks 的魅力。每个例子都简单实用,保证你看完就能用起来。准备好了吗?让我们开始这场自定义 Hooks 的冒险吧!
什么是自定义 Hooks?
自定义 Hooks 就是把常用的逻辑抽取成一个可复用的函数。它通常以 use 开头(React 的命名约定),内部可以调用其他 Hooks(如 useState、useEffect),然后返回你需要的数据或功能。简单来说,它就像个“工具箱”,随时拿来用,省时又省力。
1. useToggle:状态切换的小能手
作用:封装一个布尔值的切换逻辑,点击一下开,再点一下关,简单又实用。
Demo:灯泡开关
import React from 'react';
// 自定义 Hook: useToggle
function useToggle(initialValue = false) {
const [value, setValue] = React.useState(initialValue);
const toggle = () => setValue(prev => !prev);
return [value, toggle];
}
// 使用自定义 Hook
function LightSwitch() {
const [isOn, toggleLight] = useToggle(false);
return (
<div>
<h3>灯泡状态:{isOn ? '开 💡' : '关 🌑'}</h3>
<button onClick={toggleLight}>开关</button>
</div>
);
}
export default LightSwitch;
讲解:useToggle 像个灯泡遥控器,初始状态是 false(关),点击按钮就切换成 true(开),再点又关掉。它返回一个数组:[当前状态, 切换函数],用起来跟 useState 一样顺手。想开灯关灯?一个 Hook 搞定!
场景:开关按钮、显示/隐藏面板、模式切换。
2. useFetch:数据请求的贴心助手
作用:封装数据请求逻辑,处理加载状态、数据和错误,省去重复写 useEffect 的麻烦。
Demo:随机笑话生成器
import React from 'react';
// 自定义 Hook: useFetch
function useFetch(url) {
const [data, setData] = React.useState(null);
const [loading, setLoading] = React.useState(true);
const [error, setError] = React.useState(null);
React.useEffect(() => {
setLoading(true);
fetch(url)
.then(response => response.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(err => {
setError(err.message);
setLoading(false);
});
}, [url]);
return { data, loading, error };
}
// 使用自定义 Hook
function JokeGenerator() {
const { data, loading, error } = useFetch('https://api.chucknorris.io/jokes/random');
if (loading) return <p>加载中...</p>;
if (error) return <p>出错啦:{error}</p>;
return (
<div>
<h3>随机笑话</h3>
<p>{data?.value || '暂无笑话'}</p>
</div>
);
}
export default JokeGenerator;
讲解:useFetch 是你的“数据快递员”,输入一个 URL,它就去取数据,回来时告诉你:加载中、拿到数据了还是出错了。返回的对象 { data, loading, error } 让你轻松处理各种状态。这次我们用它从 API 抓了个 Chuck Norris 的笑话,够酷吧?
场景:API 请求、加载外部资源。
3. useLocalStorage:本地存储的记忆大师
作用:封装 localStorage 操作,自动同步状态和本地存储,数据永不丢失。
Demo:便签记录器
import React from 'react';
// 自定义 Hook: useLocalStorage
function useLocalStorage(key, initialValue) {
const [value, setValue] = React.useState(() => {
const storedValue = localStorage.getItem(key);
return storedValue ? JSON.parse(storedValue) : initialValue;
});
React.useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}
// 使用自定义 Hook
function NoteTaker() {
const [note, setNote] = useLocalStorage('myNote', '');
return (
<div>
<h3>我的便签</h3>
<textarea
value={note}
onChange={(e) => setNote(e.target.value)}
placeholder="写点什么吧..."
rows={5}
cols={30}
/>
<p>刷新页面试试,内容不会丢哦!</p>
</div>
);
}
export default NoteTaker;
讲解:useLocalStorage 像个“记忆大师”,把你的便签存在浏览器里,刷新页面也不会丢。初始值从 localStorage 读取,没数据就用默认值。每次更新时,它默默同步到本地存储,简直是懒人福音!
场景:表单持久化、用户偏好设置。
自定义 Hooks 的魔法公式
写自定义 Hooks 其实很简单,记住这三步:
- 命名:以 use 开头,比如 useToggle。
- 逻辑:用内置 Hooks(如 useState、useEffect)封装功能。
- 返回:返回需要的值或函数,供组件使用。
它就像把一堆杂乱的工具收拾进一个箱子,拿出来就能用,还能分享给别人。
为什么自定义 Hooks 这么香?
- 复用性:一个 Hook 写好,到处用,告别复制粘贴。
- 可读性:逻辑集中,组件更干净,像拆礼物一样清晰。
- 灵活性:想加功能?改 Hook 就行,组件不用动。
试想一下,没有 useFetch,每次请求都要写一堆 useEffect 和状态管理,多累啊!
总结:解锁你的 Hooks 创意
这三个 Demo 只是自定义 Hooks 的冰山一角:
- useToggle:开关大师,状态切换一把抓。
- useFetch:数据小助手,API 调用so easy。
- useLocalStorage:记忆专家,数据永存不怕丢。
动手试试这些代码,或者自己造个 Hook,比如 useWindowSize(监听窗口大小)或 useDebounce(防抖输入)。React 的世界因 Hooks 更精彩,你的创意是下一把“魔法钥匙”!有想法吗?欢迎留言分享你的自定义 Hooks!
关键词:React 自定义 Hooks、useToggle 示例、useFetch 数据请求、useLocalStorage 本地存储、React Hooks 实战教程。