利用React 自定义Hooks实现业务逻辑复用实例(1)

// PostsAndTodos.js

useEffect(() => {

const loadPosts = async () => {

setIsPostsLoading(true);

try {

let response = await fetch(

“https://jsonplaceholder.typicode.com/posts?_limit=5”

);

let data = await response.json();

setPosts(data);

} catch (e) {

console.log(e);

}

setIsPostsLoading(false);

};

loadPosts();

}, []);

  1. 我们首先在 useEffect 里定义了 loadPosts() 函数,用来请求远程数据。

  2. loadPosts()函数里,我们在请求开始,设置加载状态为true,在结束时,无论是否出错,都把加载状态设置为false

  3. 然后函数中间,我们发起请求,把返回的数据更新到 state 中。

加载 Todos


加载 todos 的代码和加载 posts 的代码基本相同,只是请求的 url 和更新状态的函数名不同:

// PostsAndTodos.js

useEffect(() => {

const loadTodos = async () => {

setIsTodosLoading(true);

try {

let response = await fetch(

“https://jsonplaceholder.typicode.com/todos?_limit=5”

);

let data = await response.json();

setTodos(data);

} catch (e) {

console.log(e);

} finally {

setIsTodosLoading(false);

}

};

loadTodos();

}, []);

展示数据


我们这里简单的使用 <ul><li> 展示 poststodos 的列表:

Posts

    {isPostsLoading ? (

    loading...

    ) : (

    posts.map(post =>

    • {post.title}
    • )

      )}

      Todos

        {isTodosLoading ? (

        loading...

        ) : (

        todos.map(todo =>

      • {todo.title}
      • )

        )}

        问题


        这样做问题显而易见,我们把请求数据的逻辑基本上重复了两遍,唯一不同的就是请求的 url,这样不符合可复用的代码设计规范,而且这个组件充斥着大量的业务逻辑和展示逻辑代码,十分臃肿,也违背了组件分离的设计原则,即负责展示的组件应当和业务处理的代码分离。那么如何进行优化呢?

        用自定义 Hooks 改造

        ========================================================================

        使用 React 自定义 Hooks,我们可以把请求数据、更新加载状态、更新错误状态的代码全部写到自定义的 Hooks 中,然后在需要它的组件中调用即可,一般只需要一行代码。接下来我们就对上边的例子进行改造。

        useRequest


        我们新建一个useRequest.js的文件,然后定义一个同名的函数:

        function useRequest(url) {

        // 代码

        // return …

        }

        React 官方推荐自定义的 Hooks 使用 use 开头,因为这样的命名规范使得阅读代码的人知道使用它可以做什么事情。这个函数有如下特点:

        • 函数可以接受参数,可以是任何此 hook 所需要的值,甚至是其他 hooks 返回的值。

        • 函数可以有返回值,给任何调用此 hook 的组件使用

        接下来我们编写它的业务逻辑,其实在使用自定义 Hooks 多次之后就会发现,函数式组件里的第一行代码到 return 之前的代码都可以直接放到自定义 Hooks 里边,因为它们都属于业务代码,而 return 中的代码负责展示逻辑。

        我们复制加载 posts 或者 todos 的代码到 useRequest 的函数中,然后稍加改动:

        // useRequest.js

        const [data, setData] = useState([]);

        const [isLoading, setIsLoading] = useState();

        const [error, setError] = useState();

        useEffect(() => {

        const loadData = async () => {

        setIsLoading(true);

        try {

        let response = await fetch(url);

        let data = await response.json();

        setData(data);

        } catch (e) {

        setError(e);

        } finally {

        setIsLoading(false);

        }

        };

        loadData();

        }, []);

        return [data, isLoading, error];

        这里我们把状态和数据的命名改为了更通用的 data, isLoading, 和 error,因为我们不限制特定 domain,任何需要加载数据的组件都可以使用此 hook。在函数的最后我们返回了 data, isLoading, error 这三个状态供调用此 hook 的组件使用,这里返回值的类型没有要求,如果返回值比较多,也可以返回一个对象,如:

        return {data, isLoading, error}

        加载 Posts 和 Todos


        现在我们再看看加载数据的代码,在新的 PostsAndTodosWithHooks.js 文件中,我们只需要在组件里调用 useRequest hook 即可进行数据抓取:

        // PostsAndTodosWithHooks.js

        const [posts, isPostsLoading] = useRequest(

        “https://jsonplaceholder.typicode.com/posts?_limit=5”

        );

        const [todos, isTodosLoading] = useRequest(

        “https://jsonplaceholder.typicode.com/todos?_limit=5”

        );

        • useRequest hook 需要一个 url 参数,即请求的数据的地址。

        • 我们接收了返回的数据和加载状态返回值,利用了ES6的语法,然后把 dataisLoading 起了别名。

        • useRequest hook中的 dataisLoading 更新时,PostsAndTodos 组件中用到这两个状态的值也会同步更新。

        • 组件渲染部分的代码不变。

        运行代码,效果和之前一致,但是代码简洁很多,hook 和展示组件各司其职,使得业务逻辑和视图的代码都变得清晰易读。而且复用业务逻辑,也使得代码量大大减少,此例则直接减少了50%。

        自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

        深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

        因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

        img

        既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

        由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

        如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

        最后

        技术是没有终点的,也是学不完的,最重要的是活着、不秃。零基础入门的时候看书还是看视频,我觉得成年人,何必做选择题呢,两个都要。喜欢看书就看书,喜欢看视频就看视频。最重要的是在自学的过程中,一定不要眼高手低,要实战,把学到的技术投入到项目当中,解决问题,之后进一步锤炼自己的技术。

        技术学到手后,就要开始准备面试了,找工作的时候一定要好好准备简历,毕竟简历是找工作的敲门砖,还有就是要多做面试题,复习巩固。有需要面试题资料的朋友点击这里可以免费领取


        链图片转存中…(img-fDmiImw3-1713697288065)]

        最后

        技术是没有终点的,也是学不完的,最重要的是活着、不秃。零基础入门的时候看书还是看视频,我觉得成年人,何必做选择题呢,两个都要。喜欢看书就看书,喜欢看视频就看视频。最重要的是在自学的过程中,一定不要眼高手低,要实战,把学到的技术投入到项目当中,解决问题,之后进一步锤炼自己的技术。

        技术学到手后,就要开始准备面试了,找工作的时候一定要好好准备简历,毕竟简历是找工作的敲门砖,还有就是要多做面试题,复习巩固。有需要面试题资料的朋友点击这里可以免费领取

        [外链图片转存中…(img-DpAgH5RO-1713697288065)]

      • 9
        点赞
      • 29
        收藏
        觉得还不错? 一键收藏
      • 0
        评论
      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

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

      抵扣说明:

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

      余额充值