用动画和实战打开 React Hooks(二):自定义 Hook 和 useCallback

本文深入探讨React Hooks,通过实例详细讲解如何创建自定义Hook和使用useCallback解决组件无限循环问题。作者通过自定义Hook实现数据获取逻辑的复用,分析自定义Hook的工作原理,并解决因函数引用变化导致的Effect无限循环。同时,介绍了记忆化缓存的概念及其在useCallback中的应用。
摘要由CSDN通过智能技术生成

在这里插入图片描述

本文由图雀社区成员 mRc 写作而成,欢迎加入图雀社区,一起创作精彩的免费技术教程,予力编程行业发展。

如果您觉得我们写得还不错,记得 点赞 + 关注 + 评论 三连,鼓励我们写出更好的教程💪

在第二篇教程中,我们将手把手带你用自定义 Hook 重构之前的组件代码,让它变得更清晰、并且可以实现逻辑复用。在重构完成之后,我们陷入了组件“不断获取数据并重新渲染”的无限循环,这时候,useCallback 站了出来,如同定海神针一般拯救了我们的应用……

欢迎访问本项目的 GitHub 仓库Gitee 仓库

自定义 Hook:量身定制

上一篇教程中,我们通过动画的方式不断深入 useStateuseEffect,基本上理清了 React Hooks 背后的实现机制——链表,同时也实现了 COVID-19 数据可视化应用的全球数据总览和多个国家数据的直方图。

如果你想直接从这一篇教程开始阅读和实践,可下载本教程的源码:

git clone -b second-part https://github.com/tuture-dev/covid-19-with-hooks.git
# 或者克隆 Gitee 的仓库
git clone -b second-part https://gitee.com/tuture/covid-19-with-hooks.git

自定义 Hook 是 React Hooks 中最有趣的功能,或者说特色。简单来说,它用一种高度灵活的方式,能够让你在不同的函数组件之间共享某些特定的逻辑。我们先来通过一个非常简单的例子来看一下。

一个简单的自定义 Hook

先来看一个 Hook,名为 useBodyScrollPosition ,用于获取当前浏览器的垂直滚动位置:

function useBodyScrollPosition() {
   
  const [scrollPosition, setScrollPosition] = useState(null);

  useEffect(() => {
   
    const handleScroll = () => setScrollPosition(window.scrollY);
    document.addEventListener('scroll', handleScroll);
    return () =>
      document.removeEventListener('scroll', handleScroll);
  }, []);

  return scrollPosition;
}

通过观察,我们可以发现自定义 Hook 具有以下特点:

  • 表面上:一个命名格式为 useXXX 的函数,但不是 React 函数式组件
  • 本质上:内部通过使用 React 自带的一些 Hook (例如 useStateuseEffect )来实现某些通用的逻辑

如果你发散一下思维,可以想到有很多地方可以去做自定义 Hook:DOM 副作用修改/监听、动画、请求、表单操作、数据存储等等。

提示

这里推荐两个强大的 React Hooks 库:React UseUmi Hooks。它们都实现了很多生产级别的自定义 Hook,非常值得学习。

我想这便是 React Hooks 最大的魅力——通过几个内置的 Hook,你可以按照某些约定进行任意组合,“制造出”任何你真正需要的 Hook,或者调用他人写好的 Hook,从而轻松应对各种复杂的业务场景。就好像大千世界无奇不有,却不过是由一百多种元素组合而成。

管窥自定义 Hook 背后的原理

又到了动画时间。我们来看看在组件初次渲染时的情形:

我们在 App 组件中调用了 useCustomHook 钩子。可以看到,即便我们切换到了自定义 Hook 中,Hook 链表的生成依旧没有改变。再来看看重渲染的情况:

同样地,即便代码的执行进入到自定义 Hook 中,我们依然可以从 Hook 链表中读取到相应的数据,这个”配对“的过程总能成功。

我们再次回味一下 Rules of Hook。它规定只有在两个地方能够使用 React Hook:

  1. React 函数组件
  2. 自定义 Hook

第一点我们早就清楚了,第二点通过刚才的两个动画相信你也明白了:自定义 Hook 本质上只是把调用内置 Hook 的过程封装成一个个可以复用的函数,并不影响 Hook 链表的生成和读取

实战环节

让我们继续 COVID-19 数据应用的开发。接下来,我们打算实现历史数据的展示,包括确诊病例、死亡病例和治愈人数。

我们首先来实现一个自定义 Hook,名为 useCoronaAPI ,用于共享从 NovelCOVID 19 API 获取数据的逻辑。创建 src/hooks/useCoronaAPI.js,填写代码如下:

import {
    useState, useEffect } from "react";

const BASE_URL = "https://corona.lmao.ninja";

export function useCoronaAPI(
  path,
  {
    initialData = null, converter = (data) => data, refetchInterval = null }
) 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值