React中自定义hook,提高开发效率,你学会了吗?

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 4 天,点击查看活动详情

大家好,我是爱吃鱼的桶哥Z,在上一篇文章中,我们介绍了几个比较好用的hooks,但有时候我们在业务中会经常重复编写一些冗余的代码,这时官方又给我们提供了一个新的内容,那就是自定义hook。通过自定义 Hook,可以将组件逻辑提取到可重用的函数中,具体的描述可以看这里

今天我们就一起来学习一下如何开发自定义hook,并在实际工作中使用到帮助我们来提高开发效率。

自定义 Hook

当我们需要在多个组件中使用相同的逻辑代码时,就需要将代码抽取到第三个函数中进行管理了,而组件和Hook都是函数,所以也同样使用与这种方式。

自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 Hook。  例如,下面的 useToggle 是我们第一个自定义的 Hook:

import React, { useState, useMemo } from 'react';

const useToggle = (defaultValue: boolean = false) => {
    const [state, setState] = useState(defaultValue);
    
    const actions = useMemo(() => {
        const setLeft = () => setState(defaultValue);
        const setRight = () => setState(!defaultValue);
        return {setLeft, setRight};
    }, []);
    
    return [state, actions];
};

上述代码主要用于在两个状态值间切换的Hook,内部的实现也很简单,我们在自定义Hook内部保存了一个state,通过改变state来修改状态,并且我们返回了两个方法,方便直接修改状态。

与 React 组件不同的是,自定义 Hook 不需要具有特殊的标识。我们可以自由的决定它的参数是什么,以及它应该返回什么(如果需要的话)。换句话说,它就像一个正常的函数。但是它的名字应该始终以 use 开头,这样可以一眼看出其符合 Hook 的规则

下面让我们一起来看一下这个自定义Hook该如何使用。

使用自定义 Hook

我们知道开发 自定义Hook 的前提就是多个组件需要提取相同的逻辑方便复用,因此我们可以在多个组件中来使用它,具体代码如下:

import React from 'react';
import useToggle from './hooks/useToggle';

const Demo = () => {
    const [state, { setLeft, setRight }] = useToggle();
    
    return (
        <div>
            <p>当前状态:{state ? '开启' : '关闭'}</p>
            <button onClick={() => setLeft()}>关闭</button>
            <button onClick={() => setRight()}>开启</button>
        </div>
    )
}

具体的效果可以狠戳这里

上面的代码中,我们可以直接通过setLeftsetRight直接修改状态,而不用自己写一个setState,然后在里面去做state的修改,这样当我们在多个组件中都有这样的需求时,可以直接拿过来就用,也不需要考虑内部是如何实现的。

扫描二维码关注公众号,回复: 14419509 查看本文章

使用 ahooks

上面的例子只是带大家认识一下什么是自定义Hook,在实际开发中,我们的自定义Hook肯定不会写的这么简单,而是需要根据实际的需求来进行代码的抽取。当然目前市面上也有很多优秀的自定义Hooks库开源出来,接下来我们要一起来使用的就是阿里开源的一款ahooks自定义Hook库,具体的文档在这里

先说一下为什么要用ahooks这个库,市面上还有那么多其它的自定义Hooks库,为什么不选择其它的呢?如果大家有开发过后台管理系统,应该都使用过antd这个UI库,而antd也是阿里开源出来的,ahooksantd一起使用,可以大大的提高开发的效率,因此这里我们选择这个自定义Hook库来进行学习和使用。

在日常的开发中,使用到antd中最多的功能应该就是表单(Form)和表格(Table)了,如果用过antd-pro-table的开发人员一定对我说的这块很熟悉了,顶部的搜索表单跟下面的展现表格数据进行联动,虽然很好用,但是antd-pro-table有一个致命的确定,那就是有任何表单数据发生改变时,表格组件也会跟着重新渲染,会导致页面非常卡顿,因此后面我们都不实用antd-pro-table了,而是直接用antd提供的Table组件,再搭配上ahooks中的useAntdTable来一起使用,开发效率也好,页面的渲染也好,都快了很多。接下来我们一起来看一下实际开发中又是如何做的。

我们经常会用到Table组件,用于展示数据,但是Table的分页和加载状态我们需要自己处理,相对来说还是比较麻烦的,而ahooks就想到了这点,给我们提供了一个useAntdTable方法,这个方法的具体API可以看这里,但是我们在实际开发中还会基于它再实现一个自定义的useTable,下面我们一起来看一下这个useTable如何实现,以及我们为什么还要再封住一层。

import { useAntdTable } from 'ahooks';

const useTable = ( service: any, options?: any) => {
    const ret = useAntdTable(service, {
        defaultPageSize: 10,
        formatResult(res: any) {
            if (res?.status === 200) {
                return {
                    total: res.data.info.results,
                    list: res.data.results
                };
            }
            throw res;
        },
        ...(options || {}),
    });
    return ret;
};

我们简单的做了一层封住,在请求成功后只返回我们需要的数组即可,但是要保证项目开发中后端的接口返回中始终都有datacount参数,这样才能做统一处理,上面的方法的实现,下面我们来看看具体该如何使用。

const getTableData = ({ current, pageSize }): Promise<Result> => {
    let query = `page=${current}&size=${pageSize}`;

    return axios(`https://randomuser.me/api?results=55&${query}`);
};

const { tableProps } = useTable(getTableData);

使用的方法也很简单,只需要将请求的方法放到useTable的参数中就可以了,至于内部做了什么处理,这些就不需要我们去关心了,我们只需要拿到对应的数据,然后做渲染即可,其中Table组件的loading状态和翻页数据,useTable内部引用useAndtTable已经帮我们处理了,具体的实现效果可以狠戳这里

image.png

当然,因为涉及到内部数据的问题,因此这里使用的ahooks提供的接口来写的,大家也可以根据你们公司自己的接口详情来对这个方法进行改造,改造后的方法比直接用ahooks提供的useAndtTable跟简便一些,还有更多好用的自定义hook在官网中,大家有需要的可以仔细的学习一下,相信可以帮助你提高不少的开发效率。

最后

我们开发自定义hook的时候,一定要遵循React官方的规则来进行编写代码,如果不按照规则来编写自定义hook,那么React就无法判断某个函数是否包含对其内部Hook的调用,React将无法自动检查你的Hook是否违反了Hook 的规则,因此根据官方的规则来进行开发是尤为重要的。

当我们需要开发一个自定义hook时,可以先到Github上面去搜一下,看看有没有相关的轮子,看看别人写的代码怎么样,这样不仅有利于我们提升自己的代码编写能力,也能避免重复造轮子。

至此,关于自定义hooks的全部内容就结束了,当然对于React自定义hook的学习和使用我们还有很长的路要走,我们一起加油吧~

如果这篇文章有帮助到你,❤️关注+点赞❤️鼓励一下作者,谢谢大家

参考文献

官方教程 自定义 Hook

ahooks 官网

猜你喜欢

转载自juejin.im/post/7126061803586453517