最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 深入React笔记 — 谈谈hooks

    正文概述 掘金(MosinNg)   2021-01-03   602

    年初的时候,从头大的flutter终于转回了老本行js代码,就此第一次开始接触了hooks。

    一开始看useState这些api其实很奇怪的,返回一个数组,第一个数组项目是value,第二个是setValue的函数。然后就是useEffect,useCallback这些,有点套不上原来class组件的思维。但一年下来,感觉非常爽,就个人感觉hooks理念相比其他前端框架跃进了一大截。

    为什么需要hooks

    从React官方提案中,列举了三个理由

    • Hooks let you reuse logic between components without changing your component hierarchy.
    • Hooks let you split one component into smaller functions based on what pieces are related.
    • Hooks let you use React without classes.

    我说下我个人理解:

    增强function组件

    这个hooks最招牌的好处,function组件本身非常简洁,但在React原来的写法中,只能承担渲染无state变化逻辑的纯组件,但引入hooks后,能使函数组件使用管理state和“管理声明周期”的能力。

    从理解上更符合React理念

    React核心过程UI=f(state),其本身就是一个函数组件。函数组件精准的阐述了React对应构建用户界面的理念。class组件更像是非必要的妥协。而且有时也有问题:函数式组件与类组件有何不同?

    而hooks对应生成最终UI的state管理就像函数式编程的嵌套调用。

    // 以下是伪代码
    
    // 函数组件我们这么写
    const APP = function () {
      const [state1] = useState();
      const [state2] = useState();
      render({
        state1, 
        state2
      });
    }
    // 就如同函数式编程的嵌套调用
    APP = React.render(
      useState2(
        useState1(
          initState
        )
      )
    );
    

    这一切看起来非常自然且易于调试理解,甚至就像dan的博客提到“Bug-O” 表示法的bug复杂度是bug(o)。

    逻辑复用

    这个写过的都知道,hooks的状态复用非常爽。其实其他框架在之前都解决了ui的组件化问题,但常常复杂工程带来的就是集成这些小组件的主控组件非常庞大,需要管理非常多的子组件状态。而hooks则可以将这些state拆分出去。

    hooks原理简述

    来看看hooks在React的数据结构。在新版filber架构中,用fiber树来表示整个vdom结构,函数组件也是一个fiber节点。fiber用child和return,sibling来指示fiber节点的子节点,父节点和兄弟节点。因此看似是个树结构,实际是个链表来串联起来的。

    深入React笔记 — 谈谈hooks

    而在每个fiber的数据结构中,有一个memoizedState属性,这个就是存储hooks的地方,每个函数组件有多个hooks,因此memoizedState也是一个链表结构,来串联起来每一个hooks。而在每个hooks节点里面,也有一个memoizedState,这里面存储着每个hooks的数据(例如state,依赖的effect等等)。

    在第一次mount阶段,会根据顺序将hooks对象生成并按照顺序一个个加入到memoizedState链表结构中。在hooks执行的时候,会有个workInProgressHook在不断指向hooks链表的最新一个节点,从而对应找到相应的hooks数据,根据更新队列queue,计算出hooks的存储数据memoizedState(所以顺序很重要)。

    将hooks加入链表后,React将hook.memoizedState和dispatch返回,dispatch则已经附上了当前的hooks状态,和当前fiber关联,然后用闭包返回保存起来,更新的时候就和当前的fiber绑定关系了。hooks执行阶段,会调用这个dispatchAction,在函数内部,会创建update对象,形成链表,存在hooks数据的queue下。

      const queue = (hook.queue = {
        pending: null,
        dispatch: null,
        lastRenderedReducer: basicStateReducer,
        lastRenderedState: (initialState: any),
      });
      // 设置queue.dispatch, 当前fiber被关联到queue.dispatch中
      const dispatch: Dispatch<
        BasicStateAction<S>,
      > = (queue.dispatch = (dispatchAction.bind(
        null,
        currentlyRenderingFiber,
        queue,
      ): any));
      //4. 返回dispatchAction操作接口
      return [hook.memoizedState, dispatch];
    

    hooks核心就两点 1. 链表 2.闭包(保留了当前的现场)。

    hooks的实践

    hooks的分散和集中

    之前说hooks的一点非常好的地方就是逻辑的复用非常方便,可以将管理state逻辑非常容易的拆分出去,但有时经常碰到“复用”过度的地方:hooks嵌套组合非常复杂,导致阅读调试非常烦。我曾经遇到的例子如下图:

    深入React笔记 — 谈谈hooks

    类似于这样吧,嵌套了四五层,设计者必须小心管理和划分每个hooks职责,但即使这样,也使得很多逻辑分散,不知道一个state的变化到底是哪里导致的,难以阅读。但如果过于hooks设计的集中又会使得代码逻辑集中庞杂,失去了hooks的优势。因此复杂项目需要把握好hooks的内聚和耦合。

    依赖追踪的陷阱

    hooks引入了副作用及依赖变化的概念。但即使hooks用了很长的时间,也经常会碰到useEffect死循环渲染,和一些不必要的重复render。官方设计了useCallback和useMemo来解决,但大型项目参与人多和代码量增大的情况下,追踪依赖就变成了挺大的调试负担。


    起源地下载网 » 深入React笔记 — 谈谈hooks

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元