React 如何自定义 Hooks

自定义 Hooks

React 内部自带了很多 Hooks 例如 useState、useEffect 等等,那么我们为什么还要自定义 Hooks?使用 Hooks 的好处之一就是重用,可以将代码从组件中抽离出来定义为 Hooks,而不用每个组件中重复去写相同的代码。首先是维护方便,更重要的是封装,Hooks 将业务逻辑进行了封装,只要返回值不变,任何改动对组件都是透明的。

Hooks的设计中,将状态保存在Filber节点上,组件是无状态的,在我们的自定义 Hooks 中通过 useState 访问数据,通过 useEfftect 做副作用逻辑处理。例如,实现一个获取在线人数的 Hooks:

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

const useOnlineUsers = (apiUrl) => {
  const [onlineUsers, setOnlineUsers] = useState(0);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchOnlineUsers = async () => {
      try {
        setLoading(true);
        const response = await fetch(apiUrl);
        if (!response.ok) {
          throw new Error('网络响应不正常');
        }
        const data = await response.json();
        setOnlineUsers(data.totalOnlineUsers);
      } catch (error) {
        setError(error.message);
      } finally {
        setLoading(false);
      }
    };

    fetchOnlineUsers();

    // 可选:设置轮询来定期更新在线用户数量
    const intervalId = setInterval(fetchOnlineUsers, 10000); // 例如,每10秒更新一次

    // 清理函数来清除 interval
    return () => clearInterval(intervalId);
  }, [apiUrl]);

  return { onlineUsers, loading, error };
};

export default useOnlineUsers;

Hooks中通过 useEffect 从后台获取用户数,在需要显示的组件中进行引用:

复制代码
import React from 'react';
import useOnlineUsers from './useOnlineUsers'; // 根据你的项目结构调整路径

const OnlineUsersComponent = () => {
  const apiUrl = 'https://api.example.com/online-users'; // 替换为你的实际 API URL
  const { onlineUsers, loading, error } = useOnlineUsers(apiUrl);

  if (loading) {
    return <div>加载中...</div>;
  }

  if (error) {
    return <div>错误: {error}</div>;
  }

  return (
    <div>
      <h1>在线用户数: {onlineUsers}</h1>
    </div>
  );
};

export default OnlineUsersComponent;

自定义 Hooks 的注意事项

  1. 命名规范

自定义 hooks 的名称应该以 "use" 开头,这不仅是为了遵循 React 的惯例,还能使其在代码中一目了然地被识别为 hooks。

复制代码
const useOnlineUsers = () => {
  // hook implementation
};
  1. 使用依赖项数组优化性能

在 useEffect 或其他 hooks 中使用依赖项数组来避免不必要的重复执行。

复制代码
useEffect(() => {
  // effect logic
}, [dependency1, dependency2]); // 只有当 dependency1 或 dependency2 发生变化时,effect 才会重新执行
  1. 返回需要的所有值

从自定义 hook 返回所有需要的状态和函数,而不仅仅是一个值。这可以让使用 hook 的组件更灵活,就像 useState 一样。

复制代码
const useCounter = (initialValue = 0) => {
  const [count, setCount] = useState(initialValue);
  const increment = () => setCount(count + 1);
  const decrement = () => setCount(count - 1);
  return { count, increment, decrement };
};

// 在组件中使用
const CounterComponent = () => {
  const { count, increment, decrement } = useCounter(10);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
};

总结

Hooks 提供了非常优雅的设计方式,通过自定义 Hooks 来提升代码的复用与封装,在日常开发中,也不要过度的使用自定义 Hooks,对于一些简单不需要封装的业务逻辑,则无需定义为 Hooks。

相关推荐
伍哥的传说几秒前
Lodash-es 完整开发指南:ES模块化JavaScript工具库实战教程
大数据·javascript·elasticsearch·lodash-es·javascript工具库·es模块·按需导入
@菜菜_达1 分钟前
Lodash方法总结
开发语言·前端·javascript
GISer_Jing7 分钟前
低代码拖拽实现与bpmn-js详解
开发语言·javascript·低代码
YAY_tyy11 分钟前
基于 Vue3 + VueOffice 的多格式文档预览组件实现(支持 PDF/Word/Excel/PPT)
前端·javascript·vue.js·pdf·word·excel
Yvonne爱编码31 分钟前
AJAX入门-AJAX 概念和 axios 使用
前端·javascript·ajax·html·js
在路上`1 小时前
前端学习之后端java小白(三)-sql外键约束一对多
java·前端·学习
Pu_Nine_92 小时前
10 分钟上手 ECharts:从“能跑”到“生产级”的完整踩坑之旅
前端·javascript·echarts·css3·html5
東雪蓮☆2 小时前
从零开始掌握 Web 与 Nginx:入门详解
运维·服务器·前端·nginx
脑子慢且灵2 小时前
【JavaWeb】一个简单的Web浏览服务程序
java·前端·后端·servlet·tomcat·web·javaee
柯南二号2 小时前
【大前端】 断点续传 + 分片上传(大文件上传优化) 的前端示例
前端