关于hooks的一点遐想

【React Hooks 的原理 - CSDN App】http://t.csdnimg.cn/DPzj6
在这里插入图片描述

浅浅笔记一下,其中关于 a = b.next = c 这一段,应该是fiber节点已经持有了对象b。c是新的hook节点,b.next 指向新节点,在链表尾部添加新节点,然后通过a返回。

关于memorizedState,在fiber节点上存在memorizedState属性,该属性指向hook链表的头节点;每个hook节点中又持有各自的memorizedState属性,hook节点上的该属性指向该hook节点对应的值,比如useref的ref.current的值。

【一文搞懂useCallback的使用 - CSDN App】http://t.csdnimg.cn/Gdvs4
关于usecallback的作用,以及什么时候使用,可以参考下这篇。usecallback的作用在于保证两次render前后的function函数是同一个函数。
如果子组件使用usememo包裹,该function传递给子组件,子组件在function每次更新时都会render。因为每次更新时,function都会被重新创建,两次传入的function是在两片不同的内存空间,子组件还是会触发一次render。
usecallback的作用在于保证每次返回同一个function,避免在usememo后还是触发了多次渲染。

usecallback只是返回同一个function,并没有阻止函数对象的创建,所以依然会有创建函数对象的开销;同时还会有监听依赖的开销、hooks挂载的开销、hooks更新的开销;在使用时需要注意是否确实需要。

同时,由于usecallback在监听到依赖项(usecallback第二个入参)变化时,才会返回新的function,需要注意function更新的时机,注意function跟随依赖项更新。

比如usestate和usecallback同时使用时,如果不添加对state对象的监听,callback函数中使用的永远是初始化时的state。具体可以参考闭包的场景,usecallback返回的function内部使用的永远是function创建时的state,也就是初始的state。
usestate的state在每次render更新时,都是一个新的变量,指向一片内存空间(假设初始对象是一个object)。
第一次render,第一次执行组件对应的函数,记state是state1,function创建,function内部使用了state1;
然后执行setstate操作;
此时第二次render,第二次执行组件对应的函数,记state是state2,function还是第一次的function,没有使用新创建的function,function内部还是指向state1。
如此,在业务代码执行时,就会出现一直是state1的场景。

import React, { useCallback, useState } from 'react'

export default function App() {
  const [count, _setCount] = useState(0)

  const setCountWithCb = useCallback(
    () => {
      _setCount(count + 1)
    },
    [],
  )

  const setCount = () => {
    _setCount(count + 1)
  }

  return (
    <div>
      <div onClick={() => setCount()}>{count}</div>
      <ChildB onClickAdd={() => {setCountWithCb()}}/>
    </div>
  )
}

const ChildB = function({onClickAdd}) {
  console.log('render B')
  return <div onClick={() => onClickAdd()}>Add</div>
}

题外,函数式组件本身就是一个函数,用来更新render树的一次性函数,不存在任何状态留存。hooks通过在fiber节点上挂载额外属性memorizedstte的方式,让函数式组件能够通过fiber读取到上一次render的值,实现和类式组件一样的效果。

函数式组件对比类式组件,优势在于不需要维护class实例,开销较小,可以类似将函数式组件看作创建/更新fiber节点的一次性道具,用完就抛弃。同时函数式组件相比类式组件,会减少一些模版代码。
个人观感,函数式组件的缺憾在于hooks的写法会导致稍大型的页面,在数据更新和管理方面很错杂。随处可见的useeffect监听和usecallback等会让数据的流转过程变得细碎,没有统一的事件流来跟踪、执行数据变化,以及处理该变化带来的副作用,会增加业务的复杂度,影响阅读和维护。

个人观感,对于通用的、内容自洽的业务组件、交互组件可以通函数式组件封装,起到随装随用的作用。而对于复杂页面,使用类式组件统一处理业务逻辑,在其中可以穿插使用函数式组件封装的通用的轮子。在实现业务的情况下,尽可能保证项目的可读性、可维护性,方便后续迭代。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值