React 自定义 Hooks 实战:三个超实用 Demo 带你飞

103 阅读4分钟

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 其实很简单,记住这三步:

  1. 命名:以 use 开头,比如 useToggle。
  2. 逻辑:用内置 Hooks(如 useState、useEffect)封装功能。
  3. 返回:返回需要的值或函数,供组件使用。

它就像把一堆杂乱的工具收拾进一个箱子,拿出来就能用,还能分享给别人。


为什么自定义 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 实战教程。