一、什么是Hook特性
目前React的组件定义方式主要有两种:函数组件和类组件。其中,类组件虽支持内部状态State并由于丰富的生命周期函数,但仍未改变JavaScript原型的本质;而函数组件虽是定义组件最简单的方式,但无法进行状态管理。
在React 16.8版本中,推出了Hook特性。Hook是一个特殊的函数,它可以让你“钩入”React的特性,即在函数组件中也能使用State及其他的React特性,不必定义Class组件。
二、针对State的Hook:State Hook
State Hook让函数组件可以实现对自身内部状态的管理,这里举经典的计数器例子:
import React, {useState} from "react";
function Example() {
const [ count, setCount ] = useState(0); // useState(initialState: 初始值)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
)
}
useState()的返回结果是一个含有两个元素的数组,即当前State及更新State的函数,对应上述的count和setCount()。同时,initialState初始值作为useState()的参数,就相当于了State的初始化,也是useState()方法的唯一参数。
注:如果需要在State属性中定义多个变量,可以多次使用useState()方法。
另外,为了保证Hook正常使用,编写代码时需要遵循以下原则:
- 只能在函数最外层调用Hook,不要再循环、条件判断或者子函数中调用
- 只能在React的函数组件中调用Hook。
三、针对生命周期的Hook:Effect Hook
当React组件是类组件时,可以在生命周期中进行一些副作用操作,如数据获取、设置订阅及手动更改组件中的DOM等。而Effect Hook就是让开发者可以在函数组件中进行同样操作的另一个Hook。
还是以计数器为例:
import React, { useState, useEffect } from "react";
function Example() {
const [ count, setCount ] = useState(0); // useState(initialState: 初始值)
useEffect(() => {
document.title = 'You clicked ${count} times'
})
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
)
}
使用useEffect()方法时,只需将需要在生命周期中操作的内容作为参数写入该方法。默认情况下,进行相关操作的函数在第一次渲染和每次更新之后都会执行。
此外,useEffect()方法还能接收第二个参数,以数组形式传入一个或多个变量。当组件更新时,会比较变化前后该组件中的变量是否相等。如果数组中的所有变量都相等,则跳过该次更新;当存在变量不同时则会执行useEffect()中的方法。
// 只有当count的值前后不相等时才会执行参数中的箭头函数
useEffect(() => {
document.title = 'You clicked ${count} times'
}, [count])
四、自定义Hook
当多个组件之间需要相同的Hook逻辑时,由于组件和Hook都是函数,因此可以将相同的部分提取到一个函数中实现共享。
import React, { useState, useEffect } from "react";
function useFriendStatus(friendID) {
const [ isOnline, setIsOnline ] = useState(null);
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline)
}
ChatAPI.unsubscribeToFriendStatus(friendID, handleStatusChange)
return () => {
ChatAPI.unsubscribeToFriendStatus(friendID, handleStatusChange)
}
})
return isOnline
}
上述代码中,useFriendStatus()函数是一个自定义Hook,其特征是名称以use开头。此时,只需要调用这个自定义的Hook,即可实现公共逻辑的复用。
五、其他Hook
除了以上介绍的Hook,函数组件还有一些其他的Hook函数,如useContext()、useReducer()、useCallback()、useMemo()、useImperativeHandle()、useLayoutEffect()、useDebugValue()等。关于他们的详细信息,可以查阅React官方网站(https://reactjs.org/docs/hooks-intro.html)