什么是Hooks?
Hooks是一类特殊的函数,适用于React的函数组件,可以让我们在不编写class的情况下使用state及其他的React特性,比如副作用处理及生命周期等。
为什么要Hooks?
Hooks主要可以解决以下几类问题:
- 在无需修改组件结构的情况下复用状态逻辑。原来的类组件如果需要封装一段可重用的逻辑,需要使用到高阶组件,不仅增加代码复杂度,同时会增加额外的组件节点。但是采用hooks的话,会更加的简单方便。
- 复杂逻辑分离,针对一些副作用进行了集中的管理,让相关的业务逻辑更加聚合。
- 使得函数组件可以进行组件的状态管理,能够满足绝大多数类组件的使用,减少对class的使用,从而避免class的一些痛点问题(this的指向等)
怎么用Hooks?
- 只能在react的函数组件或自定义的Hook中调用。
- 只能在函数的最外层调用Hook。不要在循环、条件判断或子函数中调用,这样是为了确保hook都能被执行,react是根据hook的执行顺序来实现多次渲染之间hooks的状态对比。
- React提供了一个检查hooks是否使用正确的插件:eslint-plugin-react-hooks
//安装
npm install eslint-plugin-react-hooks --save-dev
//eslint配置文件
{
"plugins": [
// ...
"react-hooks"
],
"rules": {
// ...
// 检查 Hooks 的使用规则
"react-hooks/rules-of-hooks": "error",
// 检查依赖项的声明
"react-hooks/exhaustive-deps": "warn"
}
}
备注:react通过调用hooks的调用顺序,来确认state对应那个useState,如果使用了条件判断语句,可能导致前后的调用顺序不一致,就会导致bug的出现
什么时候用Hooks?
- 需要向函数组件中添加state的时候
- 想要在函数组件中使用一些副作用的时候
- 想要实现props广播的时候
常见Hooks
1.useState
useState能够给函数组件引入state来实现函数组件的 状态管理,组件内部可以通过setState来修改state的值。state的变化同样会触发组件的重新渲染。
// 引入
import React, {
useState } from 'react'
...
// 数组解构,stateInit只会在初始创建state时有效,后续重复渲染时,会采用已存在的state
const [state, setState] = useState(initialState)
// 设置state
setState(state)
...
- 根据实际场景来声明state,state的内容应该尽可能在逻辑上独立和解耦,方便后期如果存在逻辑抽离的改造。
- useState的入参允许是一个函数,当我们的值依赖于旧的state时,就可以采取函数作为入参的方式。
- initialState允许是一个函数,方便应对需要经过复杂处理得到初始值的情况。
- useState不会自动合并更新对象,可以采取展开运算符来达到合并对象的效果。
- 调用state的更新函数并传入当前的 state 时,React 将跳过子组件的渲染及 effect 的执行。
- setState是一个异步的处理机制,state值发生变化后会触发重新渲染。
- state中永远不要保存可以通过计算得到的值,这种可以通过声明变量或者利用一些cache的机制保存。
2. useEffect
useEffect在渲染后判断依赖并调用,通过useEffect可以实现在函数组件中执行副作用(数据获取、设置订阅、记录日志以及手动更改React组件中的DOM)操作。useEffect支持通过返回一个清除函数的方式,来实现组件卸载的时候执行必要的一些清除操作。
// 引入
import React, {
useEffect } from 'react'
...
useEffect(() => {
document.title = `You clicked ${
count} times`;
});
// useEffect
useEffect(()=>{
function handleStatusChange(status) {
setIsOnline