React Hooks 笔记
date
Nov 7, 2020
slug
react-hooks-note
status
Published
tags
Reactjs
summary
react hooks尝鲜笔记,内含;常见hook的用法以及常见问题
type
Post
为什么学习hook?hooks 出现的意义hooks 应用场景hooks 使用所有的hook(除state)都会在组件更新后重新执行useStateuseEffectuseLayoutEffectuseMemouseCallbackuseRefuseContextuseReducer提示
为什么学习hook?
- 高效开发
- 提高组件复用性
- 提高逻辑复用性
- 提升性能
- 将复杂功能模块化更清晰、更彻底
hooks 出现的意义
- hooks之间的状态独立,有自己独立的上下文,不回出现状态混淆的情况
- 让函数组件有了状态管理
- 解决了复杂组件不直观、类组件难维护、逻辑不易复用的问题
hooks 应用场景
- 利用hooks取代生命周期函数
- 给函数组件加上状态
- 组件辅助函数(自定义hook)
- 处理发送请求
- 存取数据
- 做好性能优化
hooks 使用
所有的hook(除state)都会在组件更新后重新执行
如何避免更新?如何拿到上一次的值?hooks faq
useState
类比 class 中的 state,初始化执行一次,函数组件更新也会执行
useEffect
是componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合,都是在render后执行的。
因为hook会在组件更新(state、prop更新)后重新执行所以effect中一些绑定的事件、订阅也需要return出去,避免内存泄漏。因为第一次触发 didmount::render ⇒ 组件更新 ⇒ remove&render ⇒ 组件更新 ⇒ remove&render ⇒ 页面关闭或者复组件通过判断逻辑丢弃子组件触发 unmount ⇒ remove 。每一个render 都对应下一个remove,这是effect的设计逻辑。
effect 被称作副作用函数:数据获取,设置订阅以及手动更改 React 组件中的 DOM 都属于副作用
useLayoutEffect
与 componentDidMount、componentDidUpdate 的调用阶段是一样的,不过始终在 effect之前执行,是在模版挂载后到componentDidMount之间(浏览器渲染jsx)执行。
但它会在所有的 DOM 变更之后同步调用 effect,读取 dom 布局并同步触发重新渲染。
需要注意在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新;建议尽可能使用标准的 useEffect 以避免阻塞视觉更新。
useMemo
主要的用途是避免不必要的函数执行(组件更新),一般作用于与主逻辑无关的功能函数
useCallback
主要场景是在复组件中缓存传给子组件的prop函数,子组件可以通过effect来监听变化:
const Parent = () => {
const [num, setNum] = useState(1)
const getDoubleNum = useCallback(() => {
return num * 2
}, [])
return (
<div onClick={() => {setNum(num + 1)}}>num: {num}</div>
<Child getDoubleNum={getDoubleNum}/>
)
}
const Children = (props) => {
useEffect(() => {
console.log('prop test update...')
}, [props.getDoubleNum])
// ...
}
如果 getDoubleNum 无第二个参数或者数组中有值跟随依赖项不断的变化缓存新函数那么就会不断出发子组件更新来;如果数组为空或者依赖项不变只执行一次,只会引起子组件首次更新(初始化)
useRef
是一个js对象
作用:长久保持数据(实例变量),不仅可以用于 DOM refs;「ref」 对象是一个 current 属性可变且可以容纳任意值的通用容器,类似于一个 class 的实例属性, 返回的 ref 对象在组件的整个生命周期内保持不变即时组件重新渲染该对象也不会发生变化。
注意:返回一个子元素索引,此索引在整个生命周期中保持不变;ref对象发生改变的时候,不通知变化。属性变更不会重新渲染
useContext
作用:让子组件不用通过传递prop就可以直接取到值
注意:上层数据发生改变,必然会触发重新渲染
一般用于多层组件传值
useReducer
作用:去仓库拿数据
注意:函数组件的redux操作
提示
Hook 就是 JavaScript 函数,但是使用它们会有两个额外的规则:
- 只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用。
- 只能在 React 的函数组件中调用 Hook。不要在其他 JavaScript 函数中调用。(还有一个地方可以调用 Hook —— 就是自定义的 Hook 中)