0.什么是 React Hooks
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
1.为什么有 React Hooks
https://zh-hans.reactjs.org/docs/hooks-intro.html#motivation
- 在组件之间复用状态逻辑很难
- 复杂组件变得难以理解
- 难以理解的 class
2.怎么用 React Hooks
1.基础
基本用法看官网即可 https://zh-hans.reactjs.org/docs/hooks-reference.html
- Basic Hooks
- useState
- useEffect
- useContext
- Additional Hooks
- useReducer
- useCallback
- useMemo
- useRef
- useImperativeHandle
- useLayoutEffect
- useDebugValue
- Custom Hooks
2.进阶:
useState:
- 陈旧闭包( stale closure https://leewarrick.com/blog/react-use-effect-explained/, https://zh-hans.reactjs.org/docs/hooks-faq.html#why-am-i-seeing-stale-props-or-state-inside-my-function )
思考下面的代码
1 | function Counter() { |
1 | function Timer() { |
- 太多的 useState, state 写成对象可不可以:可以,但需自己手动合并更新对象
https://zh-hans.reactjs.org/docs/hooks-reference.html#functional-updates
1 | setState(prevState => { |
useReducer 是另一种可选方案,它更适合用于管理包含多个子值的 state 对象。
useEffect:
与生命周期对应
- componentDidMount
1 | componentDidMount() { |
- componentWillUnmount
1 | componentWillUnmount() { |
1 | // 结合看看 |
- componentDidUpdate
1 | const mounting = useRef(true); |
模拟生命周期只是方便初学 hooks 的人快速理解,但想要深入理解,我们不应该用生命周期的方式看待 useEffect(
https://overreacted.io/zh-hans/a-complete-guide-to-useeffect/ )
- 每次 Render 都有自己的 Props 与 State
- 每次 Render 都有自己的事件处理
- 每次 Render 都有自己的 Effects
useLayoutEffect
官网讲了作用,这里给一个实际的例子
useMemo 与 useCallback:
- 作用演示
- 使用 useMemo 实现 useCallback
useCallback(fn, deps) 相当于 useMemo(() => fn, deps)。
useRef
类似实例变量的东西 https://zh-hans.reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables
- useRef 解决 stale closure 问题
1 | function Timer() { |
- 但不能没有 useState
1 | // This won’t work: |
有了 useReducer 是不是不需要 redux 了?
一定程度上是,但对于我们平时做的项目来说还有很多事要做。
useReducer + useContext + useEffect 才能替代 Redux + Connect + Redux 中间件方案
3.React Hooks 原理
“手写 Hooks”
useState
useEffect
useMemo
- “setState”(useState 中的第二个返回值统称)才会更新
- 维护一个存储所有 Hooks 的数据结构,一个一个 Hook 处理,处理完递增
- 对依赖的存储和比较
手写代码的问题:
- 数据结构:数组 vs 链表
- render()部分的具体实现:如何与当前 FC 绑定而不是 Render All?获取当前 fiber
源码:
https://github.com/facebook/react/blob/master/packages/react/src/ReactHooks.js
https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberHooks.js
Memoization
1 | function memoize(fn) { |
4.React Hooks 不足
- 暂时不能取代的 API:
getSnapshotBeforeUpdate, getDerivedStateFromError, componentDidCatch
可能会有 useCatch(() => {})
6.参考
- 官网:https://zh-hans.reactjs.org/docs/hooks-intro.html
- 丹·阿布莫夫博客:https://overreacted.io/zh-hans/a-complete-guide-to-useeffect/
7.实例
https://www.jianshu.com/p/a47c03eaecba
1 | // Hook |