React开发日记-React hook

205 阅读4分钟

主要内容

  • why Hook
  • 开发使用到的 react hook:useState,usEffect,useRef,useMemo
  • 自定义Hook

why Hook

  • 如果你在编写函数组件并意识到需要向其添加一些 state,以前的做法是必须将其它转化为 Class。现在你可以在现有的函数组件中使用 Hook。解决了 function component没有State的问题,简单来说 ta是react 组件的另一种表现形式。

官方例子🌰

放上两个等价的组件实现感受一下

以前我们认为函数组件是无状态的,react hook为函数组件增加了状态,实现了和class相同的feature

  • 解决了把相关逻辑分别放在几个方法中,却又在一个方法中包含了几个不相关逻辑的问题

举个例子🌰

当需要实现一个订阅功能时,在class中使用如下方式实现,订阅逻辑被分散在三个地方,而他们是同一个功能

在hook中我们则可以使用useEffect讲订阅功能写在同一个effect中,实现订阅于取消订阅。

而如果是不同的功能 ,我们可以选择将他写在不同的effect中,使代码更易于理解

而在class中,由于我们是按照生命周期的方式书写代码,因此会出现多块功能的代码耦合写在一个函数中的情况

  • Hook 减少了调用this.state /通过this.state访问属性/所有需要操作setstate的函数需要并且需要bind(this)的繁琐 因为state是在function这个scope里面的,因此可直接访问

在上个官方例子

Hook介绍

  • 具体使用可参照官方文档,这里写一些需要注意的点

useState

  • setState导致函数组件的重新渲染 ,重新渲染时会记住state当前的值。同Class的state

useRef

  • 在组件更新后,每次重新执行,都是返回的都是同一个 ref对象,但ref.current的值会改变,

除了用来操作dom,ref还可以用于存储各种类型的数据。

当我们实现定时器的功能,并且在事件回调中清除监听时,需要用到它。因为ref.current值被set后,能在当前帧拿到最新值而不需要像state一样等到下一个帧。

上个🌰

假设我们将定时器的id存储在state中,就会造成组件的重复渲染。消耗性能。

  • ref.current 值是立即改变的。

eg.setCount(somevalue),count的最新值在下一帧拿到

如果立即访问count,此时还是旧值。

ref.current的值是立即更新的,可以随时使用。

当我们需要同时获得useState的触发视图重渲染和useRef的即时更新特性时,可以考虑实现一个自定义Hook。(例子来自ai-mark项目)

useEffect

  • 每次DOM挂载或者更新完成之后执行(可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。)
  • 不会阻塞浏览器渲染视图,使应用看上去响应更快
  • 可以在一次调用内写完订阅和取消订阅,不需要拆分功能相同的逻辑代码(上面提到过了)
  • useEffect 的的二个参数的作用

传某个变量,当变量改变,才会重新执行effect

传[ ],只有组件mounted的时候会执行一次

传null,组件每次重新render都会执行

useMemo

  • 类似Vue中的计算属性,只有在依赖改变时重新计算。

自定义hook

  • 用于组件间共享hook相关逻辑 解决了Class没有的特性 它的本质也是函数调用 ,因此不同的调用会有不同的scope,使用时里面的state是独立的。

(如何自定义请参考 自定义Hook

总结

  • 需根据不同场景使用不同hook
  • 在判断语句内调用hook导致 bug,因为react对于hook每次rerender的执行顺序都有严格要求
  • react hook不是一个breaking change,虽然官方推出了此功能,但我们仍然可以使用class
  • 不推荐将class改造成function component,比较浪费成本。需要的话在新的组件中尝试即可
  • 欢迎补充,欢迎指正..

参考文章

React官网