前段时间看了大佬卡颂理解 Hooks 的视频 👉 9分钟掌握React Hooks正确认知,很精彩。正好接触 React 也有四五个月的时间了,做项目时断断续续过了一下 React Hooks 的官方文档,视频中有的句子感觉读起来不顺口,所以整理了一下,做个笔记吧~
理解 Hooks 的方式
在学习新的技术时,类比是常用的方法,用之前理解的概念去类比新的知识点,可以很快理解新的内容。所以当函数组件引入了 Hooks 的概念后,往往都是去类比 Class components。即使官方文档也直接说 useEffect similar to componentDidMount and componentDidUpdate 😂
要用生命周期去理解 Hooks 是不合适的,Hooks 提供状态给函数组件,而函数组件本来就没有生命周期的说法。个人觉得用生命周期去理解useEffect,在遇到状态变化组件不更新的时候,会带来一些心智负担😅
视频介绍了一个很通俗易懂的方式去理解 Hooks:自变量和因变量。
学过初中的数学的都知道对于上面的二元一次方程, 被称作自变量, 被称作因变量。
下面来看看如何理解。
useState
定义了一个函数组件:
import { useState } from 'react'
export default function App() {
const [x, setX] = useState(0)
const changeX = () => setX(x + 1)
return (
<ul onClick={changeX}>
<li>x 是 {x}</li>
</ul>
)
}
触发点击事件会更新 x,x 更新,视图也会更新。
加上因变量 y
import { useState } from 'react'
export default function App() {
const [x, setX] = useState(0)
+ const y = 2 * x + 1
const changeX = () => setX(x + 1)
return (
<ul onClick={changeX}>
<li>x 是 {x}</li>
+ <li>y 是 {y}</li>
</ul>
)
}
自变量 x 的改变,让因变量 y 改变,y 对应的视图也会改变
useMemo 和 useCallback
使用 useMemo,useCallback 需要缓存的因变量
useMemo缓存因变量( 这里是y),需要显示的指定该因变量依赖的自变量useCallback缓存函数类型的因变量( 这里是changeX),同样需要显示的指定因变量的依赖的自变量
+ import { useState, useMemo, useCallback } from 'react'
export default function App() {
const [x, setX] = useState(0)
- const y = 2 * x + 1
+ const y = useMemo(() => 2 * x + 1, [x])
- const changeX = () => setX(x + 1)
+ const changeX = useCallback(() => setX(x + 1), [x])
return (
<ul onClick={changeX}>
<li>x 是 {x}</li>
<li>y 是 {y}</li>
</ul>
)
}
区别是,如果 x不变始终读取的是缓存的值。如果不使用,每次执行函数组件会创建新的y,changeX
useEffect
使用 useEffect 处理副作用,往往是因为某个自变量引起的。
那么什么是副作用?可以理解为对环境产生的影响就是产生了副作用
(注意:对环境的影响可以是好的也可以是不好的。所以副作用不一定是不好的)
比如 js 运行的环境是浏览器,浏览器提供了 DOM,那么对 DOM 的操作就在对环境产生影响。
继续上面的代码
+ import { useState, useEffect } from 'react'
export default function App() {
const [x, setX] = useState(0)
const y = 2 * x + 1
const changeX = () => setX(x + 1)
+ useeffect(() => {
+ document.title = x;
+ }, [x])
return (
<ul onClick={changeX}>
<li>x 是 {x}</li>
<li>y 是 {y}</li>
</ul>
)
}
useStste 定义的自变量 x, x 变化不仅可以触发视图变化,还能触发副作用。
小结:
-
useState定义自变量 -
useMemouseCallback定义没有副作用的因变量 -
useEffect定义有副作用的因变量
那么还剩:
-
useReducer是把多个 state 合并为一个,本质上是自变量。 -
useContext解决跨组件层级传递自变量
useRef
在自变量和视图之间做一些事情,往往需要借助某个变量(这个变量和视图没有直接关系),也可以放在自变量和因变量有关系的地方。
(这里我还需要多多想想有什么相关的例子)
示意图
感受
不要用组件生命周期去理解 Hooks,尤其对于之前用 Vue 的我来说,一开始会把生命周期当作万金油,用 React 的 Class componets 的时候,亲切到不行,心想明明都一样嘛……虽然之前项目也有用过 Vue3 的 Composition API,但当时的体会是都写在 setup 里面好乱啊。。。慢慢了解了一些编程范式后,体会到可能 Vue3 的正确使用方式也是 Hooks。