一,Hooks是什么?
在React中函数组件是没有React state 、生命周期这些功能的。在React16.8之前的模式是 class 组件(提供状态) + 函数组件(展示内容) ;React16.8之后,React提供了Hooks钩子函数,它使函数组件提供了状态、生命周期等原本 在Class 组件中才提供的功能。
Hooks带来的好处:
-
函数本身比较简单,提供了Hooks的函数组件可以更好的胜任根据状态来渲染UI这件事
-
hooks让函数组件内部有了维护状态的能力
-
hooks带来了组件的逻辑复用能力
二,第一个Hooks- useState
1,导入useState函数
import { useState } from 'react'
2,调用 useState 函数,传入初始值,返回状态和修改状态的函数
const [ count , setCount ] = useState(0)
- 参数:状态初始值。比如,传入 0 表示该状态的初始值为 0
- 注意:此处的状态可以是任意值(比如,数值、字符串等),而 class 组件中的 state 必须是对象
- 返回值:数组,包含两个值:1 状态值(state) 2 修改该状态的函数(setState)
3,在标签内使用
<div>
<h1> count:{count}</h1>
<button onClick={() => { setCount(count + 1) }} > count+1 </button>
</div>
效果:
useState的使用规则:
- useState只能直接出现在 函数组件 内部
- useState不能嵌套在 if/for/ 原因: React 是按照 Hooks 的调用顺序来识别每一个 Hook,如果每次调用的顺序不同,导致 React 无法知道是哪一个 Hook。 可以通过开发者工具进行查看
三,useEffect-理解副作用
什么是副作用:副作用(Side Effects;Adverse Reactions)系指应用治疗量的药物后所出现的治疗目的以外的药理作用
个人理解:事物的主要作用之外的,就是副作用。
在函数组件中
-
主作用:就是根据数据(state/props)渲染 UI
-
副作用:数据(Ajax)请求、手动修改 DOM、开启定时器,清空定时器,添加事件监听,删除事件, localStorage 操作等
1,使用方式:
导入useEffect
// 1. 导入useEffect
import { useEffect } from 'react'
// 2. 使用useEffect
useEffect(() => {
console.log('useEffect 1 执行了,可以做副作用')
})
useEffect(() => {
console.log('useEffect 2 执行了,可以做副作用')
})
案例:发送axios
import React, { useEffect } from 'react'
import ReactDom from 'react-dom'
import axios from 'axios'
export default function App () {
// const id = 100
// 组件挂载完成,发ajax
useEffect(() => {
const getData = async () => {
const res = await axios({
url: 'https://www.escook.cn/api/cart/',
method: 'GET'
})
console.log(res)
}
getData()
}, [])
return <div>组件挂载完成,发ajax</div>
}
ReactDom.render(<App />, document.getElementById('root'))
执行时机
render工作完成之后,执行Effect;
如果定义了多个,则顺序执行;
2,useEffect的依赖项
useEffect有两个参数:
参数1: 副作用函数。
参数2:执行副作用函数的依赖项:它决定了什么时机执行参数1(副作用函数)
useEffect(() => {
// 副作用函数的内容
}, [依赖项] )
3, useEffect的完整格式
情况1:不带第二个参数。执行时机:每次更新之后都要执行
情况2:带第二个参数,参数是空数组。执行时机:只执行第一次
useEffect(() => { // 副作用函数的内容 }, [依赖项] )
使用场景:1 事件绑定 2 发送请求获取数据 等。
情况3:带第二个参数(数组格式),并指定了依赖项。执行时机:(1)初始执行一次 (2)依赖项的值变化了,执行一次
useEffect(() => { // 副作用函数的内容 }, [依赖项1,依赖项2,....])
这里的依赖项就是组件中定义的状态。
useEffect典型应用场景-定时器
import React, { useState, useEffect, useRef } from 'react'
import ReactDom from 'react-dom'
export default function App () {
const [canSend, setConSend] = useState(true)
const [count, setCount] = useState(0)
const timer = useRef(null)
const send = () => {
// 1 按钮不可用
setConSend(false)
// 2 开始倒数
setCount(5)
timer.current = setInterval(() => {
setCount((count) => count - 1)
}, 1000)
}
useEffect(
() => {
return () => {
if (count === 1) {
// 清除定时器
clearInterval(timer.current)
// 3 倒数结束,恢复按钮
setConSend(true)
}
}
},
[count]
)
return (
<div>
模拟手机验证
<button disabled={!canSend} onClick={send}>
{canSend ? '发送验证码' : count + '秒后重新发送验证码'}
</button>
</div>
)
}
ReactDom.render(<App />, document.getElementById('root'))
效果: