前言–useEffect的简介
使用钩子函数useEffect可以实现组件的副作用。
useEffect(希望执行的动作, [组件状态的列表]);
第二个参数用来处理useEffect调用的时机,是一个数组,数组内是组件状态的列表。
例如,想要实现每次点击计数器的同时更新网站的标题,那么useEffect的处理时机就应该是count state变化后,所以在第二个参数的列表中填入count。
useEffect(() => {
document.title = `点击了${count}次`;
}, [count]);
下文以该组件为例:
import React, { useState, useEffect } from "react";
const App = () => {
const [count, setCount] = useState(0);
const [list, setList] = useState([]);
useEffect(() => {
document.title = `点击了${count}次`;
}, [count]);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((response) => response.json())
.then((data) => setList(data));
}, []);
return (
<div>
<button
onClick={() => {
setCount(count + 1);
}}
>
Click
</button>
<span>count: {count}</span>
<div>
{list.map((item, index) => (
<span key={index}>{item.name}</span>
))}
</div>
</div>
);
};
export default App;
一、useEffect模拟componentDidMount
当useEffect的第二个参数传入空列表时,相当于模拟生命周期函数componentDidMount。这个副作用仅在组件第一次挂载ui的时候调用一次。
用它来模拟组件初次挂载时,访问api、获得数据:
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((response) => response.json())
.then((data) => setList(data));
}, []);
二、useEffect模拟componentDidUpdate
如果在使用useEffect时不带上第二个参数,就相当于模拟了生命周期函数componentDidUpdate。每次渲染结束的时候都会被调用。
如果上面的例子去掉第二参数,像下面这样:
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((response) => response.json())
.then((data) => setList(data));
});
- 在每次渲染后被执行,调用API更新list;
- 由于list的更新,ui会再次渲染;
- 程序就陷入了死循环。
因此,要谨慎使用第二个参数为空的情形。
三、useEffect模拟componentWillUnmount
在useEffect中返回一个函数用于模拟component WillUnMount
useEffect(() => {
let timerId = window.setInterval(() => {
console.log(Date.now())
}, 1000)
// 返回一个函数用于模拟 WillUnMount
return () => {
window.clearInterval(timerId)
}
}, [])