useState
和 useEffect
是 React 中两个非常重要的 Hooks,它们分别用于状态管理和副作用处理。
useState
是一个用于在函数组件中添加局部状态的 Hook。它接受一个初始状态作为参数,并返回一个包含两个元素的数组:当前状态和一个更新该状态的函数。
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect
是一个用于处理副作用(如数据获取、订阅或手动更改 DOM)的 Hook。它接受两个参数:一个副作用函数和一个依赖数组。
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // 仅在 count 更新时重新运行 effect
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
在上面的 Example
组件中,我们结合使用了 useState
和 useEffect
:
useState
来管理 count
状态。useEffect
来更新文档标题,每当 count
变化时。这样,每次点击按钮增加 count
时,文档标题都会相应地更新。
如果在 useEffect
中直接调用状态更新函数,并且依赖数组中包含了该状态,可能会导致无限循环。
useEffect(() => {
setCount(count + 1); // 错误:会导致无限循环
}, [count]);
解决方法:确保 useEffect
中的状态更新逻辑不会直接依赖于当前状态,或者使用函数式更新。
useEffect(() => {
const timer = setTimeout(() => {
setCount(prevCount => prevCount + 1);
}, 1000);
return () => clearTimeout(timer); // 清理定时器
}, []); // 空依赖数组,仅在组件挂载时执行一次
如果在 useEffect
中进行异步操作(如数据获取),需要确保正确处理异步函数的返回值。
useEffect(() => {
let isMounted = true;
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
if (isMounted) {
setData(data);
}
});
return () => {
isMounted = false; // 组件卸载时取消异步操作
};
}, []);
通过这种方式,可以避免在组件卸载后更新状态,从而防止内存泄漏。
总之,useState
和 useEffect
是 React Hooks 中非常强大的工具,合理使用它们可以大大简化组件逻辑和提高代码的可维护性。
领取专属 10元无门槛券
手把手带您无忧上云