动机
React官网和2018年的React conf上都提到了动机这个东西,那么出现hooks的动机是什么?是什么推动了hooks的出现?先来看一下Hooks的动机。
1.在组件间复用状态逻辑很难
React没有提供可复用性行为“附加”到组件的途径,在写类组件的时候,一个类是一个闭包并且state在组件间传递并不怎么友好,虽然可以使用props和高阶组件来解决,但是这样会组件的结构更麻烦。如果你在 React DevTools 中观察过 React 应用,你会发现由 providers,consumers,高阶组件,render props 等其他抽象层组成的组件会形成“嵌套地狱”。
2. 复杂组件变得难以理解
React中的类组件是很重的,比如说我就想实现一个非常简单的功能,必须要带一堆钩子函数,让一个简单的组件变得很复杂。而且由于不同的生命周期在不同的阶段调用,导致我们会在相应的地方作一些处理,有可能把一些完全不相干的代码因为执行周期相同必须放在同一个生命周期中,很容易引发bug。
3. 难以理解的class
文档上说这点主要是学习class是一个难点。因为我自己写es6 class有一段时间了,所以class对我自己来说还是可以的,并且this理解的还可以。
什么是Hooks?
那么什么是Hook,Hook顾名思义就是钩子的意思。在函数组件中把React的状态和生命周期等这些特性钩入进入,这就是React的Hook。
特指表明React的Hook作用是把类组件的一些特性钩入函数组件中,因在类组件中是不可以使Hook的。
Hooks的使用规则
Hook就是javascript函数,但是使用有两个规则:
- 只能在函数的最外层调用hook。不要在循环、条件判断或者子函数中调用。(这个关系到了hooks的执行机制,会在下面hook中说到)
- 只能在React的函数组件中调用Hook。不要在其他javascript函数中调用(自定义hooks中也可以调用)
使用Hooks的好处
- 使用hooks,如果业务变更,就不需要把函数组件修改成类组件。
- 告别了繁杂的this和合并了难以记忆的生命周期。
- 支持包装自己的Hooks(自定义Hooks),是基于纯命令式的api。
- 更好的完成状态之间的共享,解决原来class组件内部封装的问题,也解决了高阶组件和函数组件的嵌套过深。一个组件一个自己的state,一个组件内可以公用。
内置的Hook
React一共内置了9种Hook。
- useState
- usEffect
- useContext
- useReducer
- useCallback
- useMemo
- useRef
- useImperativeHandle
- useLayoutEffect
useState
以前的函数式组件被成为纯函数组件或者无状态组件,是只能接受父组件传来的props并且只能做展示功能,不能使用state也没有生命周期。
现在State Hook 可以让函数式组件使用状态。
useState是React的一个Hook,它是一个方法,可以传入值作为state的默认值,返回一个数组,数组的第一项是对应的状态(默认值会赋予状态),数组的第二项是更新状态的函数。
import React, { useState } from "react";
const Greeting = () => {
const states = useState(0);
const count = states[0];
const setCount = s