我们知道,react中有两种组件:函数式组件和class组件。
在react早期版本中,只有class组件能管理状态和使用生命周期钩子。
在2019年,从react 16.8.x版本开始增加了hooks。Hooks是能让我们不用编写class,在函数组件里"钩入"React state及生命周期等特性的函数。
后来经过发展,hooks的定义为:
一系列以
“use”
作为开头的方法,它们提供了让你可以完全避开class式写法
,在函数式组件中完成生命周期、状态管理、逻辑复用等几乎全部组件开发工作的能力。
hooks提供了在函数式组件中完成开发工作的能力。
本文以最基础的hooks为例说明他在react中的作用。
State Hook:React.useState()
我们知道在class组件中可以通过this.state拿到状态,如下所示
export default class Demo extends Component {
constructor () {
this.state = {
name: 1
}
}
render() {
return (
<div>{this.state.name}</div>
)
}
}
但是函数式组件中是没有这个state的,只有用到useState,才能初始化和更新状态。 State Hook使函数式组件也有state状态,并且能进行状态的读写操作。
export default function Demo() {
const [name, setName] = useState(1) // useState的返回值是状态和状态更新的方法。
return (
<div>{name}</div>
)
}
Effect Hook:React.useEffect()
useEffect其实是处理副作用的操作。
react中的副作用:
- 发送ajax请求
- 定时器
- 手动更改真实DOM
举个例子,在页面挂载后开启定时器每300ms更新一次,在页面卸载时清除定时器。
class组件能使用生命周期钩子,那么可以如下操作:
export default class Demo extends Component {
state = {count: 0, timer: null}
componentDidMount () {
let timer = setInterval(() => {
this.setState({count: count+1})
}, 300)
this.setState({timer})
}
componentWillUnmount () {
clearInterval(this.state.timer)
}
render() {
return (
<div>{this.state.count}</div>
)
}
}
但是函数式组件中不能使用生命周期钩子,那么就需要使用副作用useEffect。
直接在useEffect中开启定时器,会出现定时器越加越快(如下面代码),直到页面崩溃的问题。这是因为useEffect会在初始化挂载和更新时都执行。
useEffect(() => {
setInterVal(() =>{
setCount(count+1)
}, 300)
})
在第二个参数加上空数组,就只在初始化挂载时执行。
useEffect(() => {
setInterVal(() =>{
setCount(count+1)
}, 300)
},[])
数组中加上任意状态值,就在该状态值更新时执行。
useEffect(() => {
setInterVal(() =>{
setCount(count+1)
}, 300)
},[count])
而对于函数式组件中卸载组件前关闭定时器,则需要用到useEffect的返回函数
在useEffect返回函数内,相当于卸载组件前
export default function Demo() {
const [name, setName] = useState(1)
useEffect(() => {
// 在此执行任何副作用
let timer = setInterVal(() =>{
setCount(count+1)
}, 300)
return () => {
// 此处相当于组件卸载前componentWillUnmount
clearInterval(timer)
}
}, [])
return (
<div>{name}</div>
)
}
总的来说:可以把Effect Hook看成三个生命周期函数的组合:
- componentDidMount
- componentDidUpdate
- componentWillUnmount
Ref Hook:React.useRef()
- Ref Hook可以在函数组件中存储/查找组件内的标签或任意其他数据
- 相当于class组件中的React.createRef()
const refContainer = useRef()
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情