React自定义hooks

在React中,自定义Hooks是一种强大的工具,允许你将组件逻辑提取为可重用的函数。以下是自定义Hooks的核心概念和实现示例:

自定义Hooks的核心要点

  1. 命名规则 :必须以 use 开头(如 useFetch),以便React识别并应用Hooks规则。
  2. 逻辑复用:封装状态管理、副作用等逻辑,避免代码重复。
  3. 组合Hooks :内部可使用useStateuseEffect等React内置Hooks。
  4. 独立状态:每次调用Hook会创建独立的状态,与调用它的组件实例绑定。

示例1:数据获取Hook(useFetch

处理异步请求,管理加载状态和错误。

jsx 复制代码
import { useState, useEffect } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const abortController = new AbortController();
    fetch(url, { signal: abortController.signal })
      .then((res) => {
        if (!res.ok) throw new Error('请求失败');
        return res.json();
      })
      .then((data) => {
        setData(data);
        setLoading(false);
      })
      .catch((err) => {
        if (err.name !== 'AbortError') {
          setError(err.message);
          setLoading(false);
        }
      });
    return () => abortController.abort();
  }, [url]); // 依赖url,url变化时重新请求

  return { data, loading, error };
}

// 使用示例
function UserList() {
  const { data, loading, error } = useFetch('https://api.example.com/users');
  if (loading) return <div>加载中...</div>;
  if (error) return <div>错误:{error}</div>;
  return <ul>{data?.map(user => <li key={user.id}>{user.name}</li>)}</ul>;
}

示例2:窗口尺寸Hook(useWindowSize

监听浏览器窗口大小变化。

jsx 复制代码
import { useState, useEffect } from 'react';

function useWindowSize() {
  const [size, setSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight,
  });

  useEffect(() => {
    const handleResize = () => {
      setSize({
        width: window.innerWidth,
        height: window.innerHeight,
      });
    };
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []); // 空依赖数组确保effect只运行一次

  return size;
}

// 使用示例
function ResponsiveComponent() {
  const { width, height } = useWindowSize();
  return <div>窗口尺寸:{width}px × {height}px</div>;
}

示例3:表单输入Hook(useInput

简化表单控件的状态管理。

ini 复制代码
import { useState } from 'react';

function useInput(initialValue) {
  const [value, setValue] = useState(initialValue);
  const handleChange = (e) => setValue(e.target.value);
  const reset = () => setValue(initialValue);

  return { value, onChange: handleChange, reset };
}

// 使用示例
function LoginForm() {
  const username = useInput('');
  const password = useInput('');

  const handleSubmit = (e) => {
    e.preventDefault();
    console.log('用户名:', username.value, '密码:', password.value);
    username.reset();
    password.reset();
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" {...username} placeholder="用户名" />
      <input type="password" {...password} placeholder="密码" />
      <button type="submit">登录</button>
    </form>
  );
}

示例4:获取上一次的值(usePrevious

跟踪状态的前一次值。

javascript 复制代码
import { useRef, useEffect } from 'react';

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value; // 在渲染后更新ref
  }, [value]);
  return ref.current; // 返回之前的值
}

// 使用示例
function Counter() {
  const [count, setCount] = useState(0);
  const prevCount = usePrevious(count);
  return (
    <div>
      当前值: {count}, 上一次值: {prevCount}
      <button onClick={() => setCount(c => c + 1)}>增加</button>
    </div>
  );
}

最佳实践

  1. 单一职责:每个Hook专注于一个特定功能。
  2. 优化性能:在effect中清理副作用(如取消请求、移除事件监听)。
  3. 类型安全:使用TypeScript定义返回类型,提升代码可靠性。
  4. 测试 :利用@testing-library/react-hooks测试Hook行为。

自定义Hooks显著提升了代码的模块化和可维护性,是构建高效React应用的关键工具。

相关推荐
草字16 小时前
uniapp 防止长表单数据丢失方案,缓存表单填写内容,放置卡退或误操作返回。
前端·javascript·uni-app
ObjectX前端实验室16 小时前
LLM流式输出完全解析之socket
前端
ObjectX前端实验室16 小时前
ChatGPT流式输出完全解析之SSE
前端·人工智能
又是忙碌的一天17 小时前
前端学习 JavaScript(2)
前端·javascript·学习
2501_9151063217 小时前
JavaScript编程工具有哪些?老前端的实用工具清单与经验分享
开发语言·前端·javascript·ios·小程序·uni-app·iphone
GISer_Jing17 小时前
计算机基础——浏览器、算法、计算机原理和编译原理等
前端·javascript·面试
我的xiaodoujiao17 小时前
从 0 到 1 搭建 Python 语言 Web UI自动化测试学习系列 8--基础知识 4--常用函数 2
前端·python·测试工具·ui
蓝瑟17 小时前
React 项目实现拖拽排序功能,如何在众多库中选对 “它”
前端·javascript·react.js
万少17 小时前
开发者注意了 DevEco Studio 6 Release 开放了,但是我劝你慎重升级6应用
前端
小刘不知道叫啥18 小时前
React 源码揭秘 | 合成事件
前端·javascript·react.js