”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 通过自定义 Hooks 在 React 中重用逻辑:实用指南

通过自定义 Hooks 在 React 中重用逻辑:实用指南

发布于2024-11-08
浏览:279

Reusing Logic in React with Custom Hooks: a Practical guide

自定义钩子是 React 中的一项强大功能,与 React 内置钩子不同,它用于更具体的目的,并且它是通过将常见功能封装到独立函数中来完成的。自定义挂钩促进可重用性、改进组件组织并整体增强代码可维护性。

在本指南中,我们将深入探讨使用自定义钩子的目的,了解创建自定义钩子的基础知识以及如何使用其他组件。然后我们将通过构建 fetch API 自定义挂钩来说明一个现实世界的示例。

了解基础知识

通常开发人员会害怕自定义挂钩这个术语,所以让我们揭开它的神秘面纱。

自定义钩子只是一个以 use 前缀开头的函数(这对于自定义钩子的工作至关重要)。
该函数由利用 React 内置钩子的可重用逻辑组成。如果您在多个组件中具有相同的逻辑,通常您会考虑使用自定义挂钩,因此通过利用自定义挂钩您可以解决多个问题,例如增强代码组织和可维护性。

创建一个简单的自定义钩子

下面的示例是一个简单的计数器自定义挂钩,它使用 useState 挂钩管理计数状态,并使用仅设置计数状态的增量或减量函数分别更新计数。

import { useState } from 'react'

const useCount = () => {
  const [count, setCount] = useState(0)

  const increment = () => setCount(prev => prev   1)
  const decrement = () => setCount(prev => prev - 1)

  return { count, increment, decrement }
}

export default useCount;

恭喜您刚刚构建了自己的自定义挂钩,这非常简单。接下来将深入探讨如何使用这个钩子

在组件中使用自定义钩子

在另一个组件中使用自定义钩子只需破坏其他组件内自定义钩子的返回值即可完成

import useCount from 'customHooks'

const Page = () => {
  const {count, increment, decrement} = useCount()

  return(
    
{ count }
) } export default Page

使用自定义钩子的真实示例

最重复的逻辑之一是获取 API,电子商务网站将获取用于身份验证、支付流程、显示所有产品、评论、评论等的数据。

您可以想象整个应用程序中重复获取逻辑的数量,可以使用自定义挂钩来简化。

本节将创建一个自定义抓取钩子。

我们将使用 useState 和 useEffect 内置 React hooks
我们将有一个数据状态,一个挂起状态(如果我们想在获取数据时显示旋转器)和一个错误状态(如果获取失败)。

下面的代码是不言自明的。在 useEffect 内部,我们定义了一个异步的 fetchData 函数,它将处理获取逻辑。在 useEffect 下面,自定义钩子将返回以下值,这些值可在所有其他组件中使用:data、pending、error。

请注意,我们正在将 url 值传递给 useFetch 自定义钩子参数,这意味着数据可以传递到自定义钩子

import {useState, useEffect} from 'react'

const useFetch = (url: string) => {
  const [data, setData] = useState([])
  const [pending, setPending] = useState(false)
  const [error, setError] = useState(null)

  useEffect(() => {
    const fetchData = async () => {
      setPending(true)

      await fetch(url)
        .then(result => {
          if (!result.ok) throw new Error('something went wrong!')
          return result.json()
        })
        .then(result => {
          setData(result)
          setPending(false)
        })
        .catch(error => setError(error))
    }

   fetchData()
  }, [url])

  return { data, pending, error }

}

export default useFetch

通过在页面组件中使用 useFetch 钩子,我们现在可以在出现错误时向客户端显示消息,在获取数据时显示旋转器,最后向客户端显示数据。

该组件可以在所有应用程序中重复使用,从而减少重复代码的数量。

import useFetch from './hooks/useFetch'
import Spinner from "./icons/Spinner"

const Page = () => {
  const {data, pending, error} = useFetch('https://jsonplaceholder.typicode.com/posts')

  if(error) 
Cloud not fetch data from the server
return( {pending ? ( ) : ( data.map((item) => (

{item.title}

{item.body}

) ) )} ) } export default Page;

结论

自定义钩子为React组件中的逻辑封装和重用提供了强大的机制,通过将通用功能提取到专用函数中,可以增强代码组织,提高可维护性,并促进代码可重用性。

我们探索了创建自定义钩子的基础知识,了解如何在 React 组件中使用它们,并展示了使用自定义钩子的真实示例。

版本声明 本文转载于:https://dev.to/kada/reusing-logic-in-react-with-custom-hooks-a-practical-guide-4li1?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何将来自三个MySQL表的数据组合到新表中?
    如何将来自三个MySQL表的数据组合到新表中?
    mysql:从三个表和列的新表创建新表 答案:为了实现这一目标,您可以利用一个3-way Join。 选择p。*,d.content作为年龄 来自人为p的人 加入d.person_id = p.id上的d的详细信息 加入T.Id = d.detail_id的分类法 其中t.taxonomy =...
    编程 发布于2025-04-07
  • 如何使用Depimal.parse()中的指数表示法中的数字?
    如何使用Depimal.parse()中的指数表示法中的数字?
    在尝试使用Decimal.parse(“ 1.2345e-02”中的指数符号表示法表示的字符串时,您可能会遇到错误。这是因为默认解析方法无法识别指数符号。 成功解析这样的字符串,您需要明确指定它代表浮点数。您可以使用numbersTyles.Float样式进行此操作,如下所示:[&& && && ...
    编程 发布于2025-04-07
  • 为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    使用php dateTime修改月份:发现预期的行为在使用PHP的DateTime类时,添加或减去几个月可能并不总是会产生预期的结果。正如文档所警告的那样,“当心”这些操作的“不像看起来那样直观。 考虑文档中给出的示例:这是内部发生的事情: 现在在3月3日添加另一个月,因为2月在2001年只有2...
    编程 发布于2025-04-07
  • 为什么我的CSS背景图像出现?
    为什么我的CSS背景图像出现?
    故障排除:CSS背景图像未出现 ,您的背景图像尽管遵循教程说明,但您的背景图像仍未加载。图像和样式表位于相同的目录中,但背景仍然是空白的白色帆布。而不是不弃用的,您已经使用了CSS样式: bockent {背景:封闭图像文件名:背景图:url(nickcage.jpg); 如果您的html,css...
    编程 发布于2025-04-07
  • 我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    将我的加密库从mcrypt升级到openssl 问题:是否可以将我的加密库从McRypt升级到OpenSSL?如果是这样,如何?答案:是的,可以将您的Encryption库从McRypt升级到OpenSSL。可以使用openssl。附加说明: [openssl_decrypt()函数要求iv参...
    编程 发布于2025-04-07
  • 在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    在Java中使用for-to-loop和迭代器进行收集遍历之间是否存在性能差异?
    For Each Loop vs. Iterator: Efficiency in Collection TraversalIntroductionWhen traversing a collection in Java, the choice arises between using a for-...
    编程 发布于2025-04-07
  • 如何有效地转换PHP中的时区?
    如何有效地转换PHP中的时区?
    在PHP 利用dateTime对象和functions DateTime对象及其相应的功能别名为时区转换提供方便的方法。例如: //定义用户的时区 date_default_timezone_set('欧洲/伦敦'); //创建DateTime对象 $ dateTime = ne...
    编程 发布于2025-04-07
  • \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    答案: 在大多数现代编译器中,while(1)和(1)和(;;)之间没有性能差异。编译器: perl: 1 输入 - > 2 2 NextState(Main 2 -E:1)V-> 3 9 Leaveloop VK/2-> A 3 toterloop(next-> 8 last-> 9 ...
    编程 发布于2025-04-07
  • 哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    在Python Matplotlib's path.contains_points FunctionMatplotlib's path.contains_points function employs a path object to represent the polygon.它...
    编程 发布于2025-04-07
  • 哪种在JavaScript中声明多个变量的方法更可维护?
    哪种在JavaScript中声明多个变量的方法更可维护?
    在JavaScript中声明多个变量:探索两个方法在JavaScript中,开发人员经常遇到需要声明多个变量的需要。对此的两种常见方法是:在单独的行上声明每个变量: 当涉及性能时,这两种方法本质上都是等效的。但是,可维护性可能会有所不同。 第一个方法被认为更易于维护。每个声明都是其自己的语句,使其...
    编程 发布于2025-04-07
  • 如何在php中使用卷发发送原始帖子请求?
    如何在php中使用卷发发送原始帖子请求?
    如何使用php 创建请求来发送原始帖子请求,开始使用curl_init()开始初始化curl session。然后,配置以下选项: curlopt_url:请求 [要发送的原始数据指定内容类型,为原始的帖子请求指定身体的内容类型很重要。在这种情况下,它是文本/平原。要执行此操作,请使用包含以下标头...
    编程 发布于2025-04-07
  • Python读取CSV文件UnicodeDecodeError终极解决方法
    Python读取CSV文件UnicodeDecodeError终极解决方法
    在试图使用已内置的CSV模块读取Python中时,CSV文件中的Unicode Decode Decode Decode Decode decode Error读取,您可能会遇到错误的错误:无法解码字节 在位置2-3中:截断\ uxxxxxxxx逃脱当CSV文件包含特殊字符或Unicode的路径逃...
    编程 发布于2025-04-07
  • 如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
    如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
    在Visual Studio 2012 尽管已安装了MySQL Connector v.6.5.4,但无法将MySQL数据库添加到实体框架的“ DataSource对话框”中。为了解决这一问题,至关重要的是要了解MySQL连接器v.6.5.5及以后的6.6.x版本将提供MySQL的官方Visual...
    编程 发布于2025-04-07
  • 如何处理PHP文件系统功能中的UTF-8文件名?
    如何处理PHP文件系统功能中的UTF-8文件名?
    在PHP的Filesystem functions中处理UTF-8 FileNames 在使用PHP的MKDIR函数中含有UTF-8字符的文件很多flusf-8字符时,您可能会在Windows Explorer中遇到comploreer grounder grounder grounder gro...
    编程 发布于2025-04-07
  • 如何在无序集合中为元组实现通用哈希功能?
    如何在无序集合中为元组实现通用哈希功能?
    在未订购的集合中的元素要纠正此问题,一种方法是手动为特定元组类型定义哈希函数,例如: template template template 。 struct std :: hash { size_t operator()(std :: tuple const&tuple)const {...
    编程 发布于2025-04-07

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3