Hooks封装与使用示例详解

2023-01-06 11:08:18
目录
Hooks是什么?Hooks解决了什么?HOC与HOOK对比分别使用React与Vue3两种框架封装useThrottle钩子函数总结

Hooks是什么?

本篇文章主要介绍Hooks如何在React与Vue3两大框架中封装使用。

Hooks就是当代码执行在某个执行阶段,触发被钩子钩到的事件函数或者回调函数,Hooks的概念最早在React的V16.8.0版本正式推出,后面Vue3的出现也引入Hooks的概念,两者使用Hooks还是会有所差异。

Hooks解决了什么?

    完善代码能力组件逻辑复用

    HOC与HOOK对比

    HOC概念:hoc是React中用于重用组件逻辑的一种高级技术实现模式,它本身是一个函数,接受一个组件并返回一个新的组件

      HOC
      function Hocomponent(WrappedComponent, selectData) {
        return class extends React.Component {
          constructor(props) {
            super(props);
            this.state = {
              data: selectData(DataSource, props)
            };
          } 
          render() {
            // ... 并使用新数据渲染被包装的组件!
            return <WrappedComponent data={this.state.data} {...this.props} />;
          }
        };
      

      上边的例子可以看出高阶组件内部返回了一个类组件,通过这个类组件对WrappedComponent进行包装,在返回得到一个全新的组件。但是HOC的缺点就是props可能会被覆盖,而且容易产生嵌套地域。

        Hooks

        react-Hooks的出现主要弥补函数组件无状态无生命周期问题等,主要应对class复杂组件变的难以理解,逻辑混乱,不易拆解和测试与嵌套地域问题。

        分别使用React与Vue3两种框架封装useThrottle钩子函数

          React实现节流Hooks
          import { useState, useCallback } from "react"; 
          export function useThrottleFn(fn, time) {
              let [isTimer,setIsTimer] = useState<any>(null);  
              const clear = () => {
                  clearTimeout(isTimer);
                  setIsTimer(null) 
              } 
              let throttle = useCallback(()=>{ 
                  if (!isTimer) {
                      setIsTimer(setTimeout(() => {
                          fn()
                          clear() 
                      }, time)) 
                  }
              },[fn, time])
              return [throttle]
          }
          // 引入使用
            const [throttle] = useThrottleFn((e)=>{
                  console.log(e)
              },500)
              const Ceshi  = ()=>{
                  let e = 'Hooks'
                  throttle(e);
              }
          

          React内部也存在很多的Hooks钩子,常用的钩子:

          useState,useMemo,useCallback,useRef,useContext,但是这些钩子必须在函数组件中使用并且在函数组件中使用钩子需要在组件顶层调用,不能在Class中使用。这样一来让我们可以挥手告别this.xxx的时代。

            Vue3实现节流Hooks
            import { ref, unref, watch } from 'vue';
            import { useTimeouts } from './useTimeout';
            /**
             *
             * @param fn 回调函数
             * @param wait 延迟时间
             * @returns
             */
            export function useThrottleFn(fn, wait = 80) {
              if (typeof fn !== 'function') {
                return;
              }
              let Timer: any = null;  
              const isReady = ref<Boolean>(false);
              const clearun = () => {
                Timer && clearTimeout(Timer);
              };
              // 闭包实现节流封装   
              return function () {
                const _this = this;
                const args = arguments;
                // 更改状态触发watch监听,触发回调函数fn
                const startFun = function () {
                  isReady.value = true;
                };
                // 这里利用watch监听isReady的状态变化执行回到函数,而不是直接将回调函数放在定时器中
                watch(
                  () => unref(isReady),
                  () => {
                    if (unref(isReady) && Timer) {
                      fn.apply(_this, args);
                      isReady.value = false;
                      Timer = null;
                      clearun();
                    }
                  },
                );
                // Timer 如果不存在就开始执行
                if (!Timer) {
                  Timer = setTimeout(startFun, wait);
                }
              };
            }
            // 引入使用
            const Ceshi = useThrottleFn(()=>{
                  console.log('Hooks')
            },300)
            

            Vue3的发布随之带来了很多新特性比如从选项式API到组合式API,引入Hooks等。那这里在介绍一个新的工具库Vueuse,Vueuse 基于Vue-demi封装了大量的钩子工具函数,比如useDark,useToggle其他点击Vueuse文档查看更多,并且在Vue2与Vue3都可以使用。当然我们也可以自己自定义按需求封装Hooks,但在Vue3中使用Hooks需要在setup中使用,由setup作为组合式API的入口点,在Vue2使用需要安装VueCompositionApi进行使用。

            总结

            React>