• React 自定义hooks最佳实践


    1. 背景

    react hooks推出已经有一段时间了,而自定义hooks在hooks中其实是非常关键的一环,它是抽离业务逻辑和UI逻辑,复用代码的关键,因此在使用上相对于其他hooks不易掌握,你可能在开发中经常会遇到以下问题

    1. 我该什么时候使用自定义hooks?
    2. 使用自定hooks时应该传入什么参数,又返回出什么值?
    3. 为什么使用自定义hooks,我的代码逻辑好像没有变简洁?

    为了解决以上疑问,下面我会结合业务的实际场景,通过几个案例,来跟大家分享自定义hooks中的一些实践与经验
    注:本文默认读者具备一定的react基础

    2. 案例一:Tabs组件

    需求一:有一个Tab选项和内容区,tab的切换,会改变tabId,需要重新拉取接口数据,用以展示不同的内容

    class实现

    我们使用class组件实现一下,来借以发现class组件中存在的一些问题
    在这里插入图片描述

    我将这个功能抽成了三个组件

    • Tab:负责切换Tab
    • ContentContainer: 负责处理数据逻辑
    • Content:负责渲染
      为什么要这么拆分的原因:将包含业务逻辑的容器组件和UI展示部分的展示组件剥离开,利于代码的复用,详细可参考:medium

    原有的class组件模式,通常是将组件拆分为UI组件和容器组件,容器组件部分处理数据逻辑,套在需要使用到该逻辑的组件上,从而达到复用代码逻辑的目的。

    因此在处理Content的时候,我将其拆成了两个组件

    • 只负责渲染的Content组件
    • 只负责逻辑处理的ContentCantainer组件
      为了复用,我们只能通过props的形式,做一层嵌套,像React中的高阶组件就是通过这种模式来实现代码逻辑的复用。
      但这种模式存在一定缺陷,组件非常复杂的时候,如果每次都通过嵌套拆分的模式来复用代码,会形成很深的组件层级和嵌套逻辑,这会给开发带来不少麻烦。而hooks的出现就解决了这个问题

    hooks改造

    针对之前遇到的问题,我们使用hooks进行改造
    在这里插入图片描述

    在class组件中,为了复用状态,我们将Content拆成了两个组件,并形成了嵌套。
    而在hooks中,我们只使用了一个组件和一个自定义hooks

    • useContent:自定义hooks,负责处理逻辑,将状态返回给外界组件
    • Content:UI组件,负责渲染
      与class不同的是,这两者并没有形成嵌套关系,而是扁平化,自定义的useContent,负责将组件逻辑抽了出来,只暴露给Content所需的状态

    案例二:Table组件

    需求二:实现一个表格组件,需要分页功能,切换不同页面时,加载不同的数据
    在这里插入图片描述

    常规实现

    这个需求,在后台十分常见,比较常见的写法如下:
    在这里插入图片描述

    在组件中我们不仅维护了Table组件的UI状态,也同时维护了Table组件的业务逻辑,定义了多个状态
    loading, dataSource , current, total
    几乎每个表格组件都会包含上述的业务逻辑,此时我们就可以将业务逻辑使用Hooks的方式剥离出来,来实现复用的目的。

    hooks改造

    在编写 useTableHooks 的时候,我们需要注意两个地方

    1. 需要将请求接口的函数作为参数传入hooks中,且该函数需要约定固定的入参和返回值
    2. 原因1:因为每个Table组件的网络请求都不一样,所以它是属于Table组件本身的逻辑,并不是useTableHooks 的逻辑,因此请求接口的函数需要在Table组件中定义
    3. 原因2:约定固定参数和返回值是为了统一在hooks中处理数据
    4. 监听表格切换的change函数,需要作为useTableHooks的返回值暴露出来,而不是在Table组件中监听change

    平时在写业务逻辑的时候,我们较少的会使用这种写法(将函数作为参数传入,将函数作为返回值传出),因此对于这两个地方需要额外的注意。

    Table组件代码如下:
    在这里插入图片描述

    useTableHooks组件代码如下:
    在这里插入图片描述

    可以看到通过自定义hooks的改造,成功的将UI逻辑和业务逻辑给分离开来,在其他地方再次使用到表格组件时,就可以直接使用 useTableHooks 去处理分页逻辑。
    整个组件变得就更加简洁可复用了。

    思考:业务要求table组件需要添加查询表单,那么自定义hooks应该如何扩展呢?
    在这里插入图片描述

    总结

    通过上面两个案例,我们可以回答最开始的几个问题了

    1. 我该什么时候使用自定义hooks?
      • 发现某处业务逻辑重复使用时,可将业务逻辑抽离开
      • 组件比较复杂时,可通过自定义hooks拆分组件逻辑,简化代码
    2. 使用自定hooks时应该传入什么参数,又返回出什么值?
      • 传参和返回值是比较灵活的,需要注意的是,不仅能传常规的数据类型,还能传递函数对象
    3. 为什么时候自定义hooks,我的代码好像没有变简洁?
      • 要理解UI组件和容器组件这两个概念,恰当的抽离业务逻辑部分,保留组件的UI部分,组件复杂时拆分可能也有一定的难度,过度设计会导致组件更难维护,因此要把控好度
  • 相关阅读:
    学姐想学SpringBoot?连夜整理了一份SpringBoot高阶笔记,涵盖六大核心专题
    用户留存为何重要?
    Rust学习----Rust安装
    2144. 打折购买糖果的最小开销-快速排序+贪心算法
    vue3基于vite打包
    JAVA计算机毕业设计预约健身私教网站Mybatis+源码+数据库+lw文档+系统+调试部署
    企业绩效管理的五种方法,你们是哪种?
    CP Autosar——EthIf配置
    触发迅雷下载
    三种内存分配的库比较
  • 原文地址:https://blog.csdn.net/qq799028706/article/details/126851871