摘要:在本教程中,您将探索 React useEffect() hook,并学习如何以及何时正确使用它。
理解 React useEffect hook
在 React 中,副作用包括数据获取、手动 DOM 操作或任何其他影响组件外部的操作。
要在函数组件中执行副作用,您使用 useEffect hook。要使用 useEffect hook,您首先需要从 react 库中导入它。
import { useEffect } from 'react';Code language: JavaScript (javascript)然后,您可以使用以下语法在您的组件中使用它。
useEffect(setup, dependencies)Code language: JavaScript (javascript)useEffect hook 是一个接受两个参数的函数。
setup是包含副作用的主要函数,您希望执行它。dependencies是一个可选的依赖值数组,它决定了setup函数何时运行。useEffecthook 将根据dependencies数组中指定的items来运行setup函数。
setup 函数可以选择返回一个清理函数。
return cleanup;Code language: JavaScript (javascript)React 在卸载组件或 setup 重新运行之前执行 cleanup 函数(除了第一次)。
在 cleanup 函数中,您可以包含用于清理资源的代码,例如清除间隔或取消网络请求 (AbortController)。
通常,您会按如下方式编写 useEffect hook。
useEffect(() => {
// Side effect code here
return () => {
// Cleanup code here (optional)
};
}, [dependencies]);Code language: JavaScript (javascript)在此语法中,您为 setup 函数定义一个箭头函数。
() => {
// Side effect code here
return () => {
// Cleanup code here (optional)
};
}Code language: JavaScript (javascript)并在 dependencies 数组中包含值。
[dependencies]Code language: JavaScript (javascript)只运行一次效果
要仅在组件挂载时运行效果(或函数),请使用空数组作为 dependencies 数组。
useEffect(() => {
// This code runs once
}, [])Code language: JavaScript (javascript)在实践中,您使用这种模式在组件的初始渲染期间运行函数。例如,您可以在组件挂载时仅运行一次从 API 获取数据的函数。
以下 UserList 组件通过调用 API 终结点 https://jsonplaceholder.typicode.com/users 来显示用户列表。
import React, { useEffect, useState } from 'react';
export default function UserList() {
const [users, setUsers] = useState([]);
const fetchUsers = async () => {
const url = 'https://jsonplaceholder.typicode.com/users';
const response = await fetch(url);
const data = await response.json();
setUsers(data);
};
useEffect(() => {
fetchUsers();
}, []);
return (
<div>
<h1>User List</h1>
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
}Code language: JavaScript (javascript)每当依赖项更改时运行效果
要运行某些值更改时的函数,您可以在 dependencies 数组中指定这些值。
以下 CounterTitle 组件利用 useEffect() hook 在 count 状态变量更改时更新文档标题。
import { useState, useEffect } from 'react';
const CounterTitle = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]);
return (
<div>
<h1>Current count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default CounterTitle;Code language: JavaScript (javascript)每次重新渲染后运行效果
要在初始渲染期间和每次重新渲染后运行函数,您只需将 setup 函数传递给 useEffect() 函数,并跳过 dependencies 数组。
例如,您可以使用 useEffect() 函数在组件渲染时以及每次重新渲染时记录一条消息。
import React, { useState, useEffect } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('Component rendered or rerendered');
});
return (
<div>
<h1>Current count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default Counter;Code language: JavaScript (javascript)运行清理函数
以下 WindowDimension 组件侦听窗口大小调整事件,并根据窗口的大小更新宽度和高度状态变量。
import { useState, useEffect } from 'react';
function WindowDimension() {
const [width, setWidth] = useState(window.innerWidth);
const [height, setHeight] = useState(window.innerHeight);
useEffect(() => {
// Define the handler function that updates the state with the window's width
const handleResize = () => {
setWidth(window.innerWidth);
setHeight(window.innerHeight);
};
// Add the event listener for window resize
window.addEventListener('resize', handleResize);
// Cleanup function: Remove the event listener when the component unmounts
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return (
<div>
<p>
Current dimension: {width}x{height}px
</p>
</div>
);
}
export default WindowDimension;Code language: JavaScript (javascript)工作原理。
首先,定义 handleResize() 函数来根据窗口的 innerWidth 和 innerHeight 更新宽度和高度状态变量。
const handleResize = () => {
setWidth(window.innerWidth);
setHeight(window.innerHeight);
};Code language: JavaScript (javascript)其次,使用 handleResize() 函数注册大小调整事件的事件侦听器。
window.addEventListener('resize', handleResize);Code language: JavaScript (javascript)第三,从 useEffect 返回一个清理函数,该函数使用 window.removeEventListener 方法删除大小调整事件侦听器。
return () => {
window.removeEventListener('resize', handleResize);
};Code language: JavaScript (javascript)这可以防止组件在从 DOM 中删除后调用 handleResize 函数,这可能会导致内存泄漏和意外行为。
总结
- 使用
useEffect(setup)在组件渲染和重新渲染时运行setup函数。 - 使用
useEffect(setup,[])在初始渲染期间仅运行一次setup函数。 - 使用
useEffect(setup, [dependencies])在组件渲染时以及每次dependencies数组中的项目更改时运行setup函数。