用 useEffect 模拟组件生命周期
useEffect
让函数组件模拟生命周期
- 默认函数组件没有生命周期
- 函数组件是一个纯函数,执行完后即销毁,自己无法实现生命周期
- 使用 Effect Hook 把生命周期 “钩” 到纯函数中
例子
import React, {useState, useEffect} from "react";
function LifeCycles() {
const [count, setCount] = useState(0)
const [name, setName] = useState('lzw.')
// 模拟 class 组件的 DidMount 和 DidUpdate
// useEffect(() => {
// console.log('此处发送一个 Ajax 请求')
// })
// 模拟 class 组件的 DidMount
useEffect(() => {
console.log('加载完了')
}, []) // 第二个参数是 [] (不依赖任何 state)
// 模拟 class 组件的 DidUpdate
useEffect(() => {
console.log('更新了')
}, [count, name]) // 第二个参数是依赖的 state
// 模拟 class 组件的 DidMount
useEffect(() => {
// let timerId = setInterval(() => {
// console.log(Date.now())
// }, 1000)
// 返回函数
// 模拟 class 组件的 WillUnMount
return () => {
clearInterval(timerId)
}
}, [])
function setVal() {
setCount(count + 1)
setName(name + '-' + count)
}
return <div>
<p>你点击了多少次 {count} 次 {name}</p>
<button onClick={setVal}>点击</button>
</div>
}
export default LifeCycles
useEffect 使用总结
- 模拟 componentDidMount - useEffect 依赖 []
- 模拟 componentDidUpdate - useEffect 依赖 [],或者依赖 [a,b]
- 模拟 componentWillUnmount - useEffect 中返回一个函数
useEffect 让纯函数有了副作用
- 默认情况下,执行纯函数,输入参数,返回结果,无副作用
- 所谓副作用,就是对函数之外造成影响,如设置全局定制任务
- 而组件需要副作用,所有需要 useEffect “钩” 到 纯函数中
用 useEffect 模拟 WillUnMount 时的注意事项
先看一个好友在线的例子
使用 class 组件实现
import React from "react";
class FriendStatus extends React.Component {
constructor(props) {
super(props);
this.state = {
status: false // 默认当前不在线
}
}
render() {
return <div>
好友 {this.props.friendId} 在线状态: {this.state.status}
</div>
}
componentDidMount() {
console.log(`开始监听 ${this.props.friendId} 的在线状态`)
}
componentWillUnmount() {
console.log(`结束监听 ${this.props.friendId} 的在线状态`)
}
// friendId 更新
componentDidUpdate(prevProps) {
console.log(`结束监听 ${prevProps.friendId} 的在线状态`)
console.log(`