如何在 useEffect 中使用 async/await?
探讨如何在 React 的 useEffect 钩子内安全地使用 async/await 处理异步操作,包括 IIFE 和单独定义函数的方法。
在 React 中,useEffect 钩子默认要求其回调函数返回一个清理函数(cleanup function)或 undefined,而不是一个 Promise。这使得无法直接在 useEffect 的回调函数上使用 async 关键字,因为它隐式返回一个 Promise,会破坏 this 行为并导致运行时错误。以下是从面试角度整理的常用方法,使用 async/await 安全处理异步操作,确保代码的正确性:
1. 在 useEffect 内使用 IIFE(Immediately Invoked Function Expression,立即调用函数表达式)
这是一种简洁方式,在回调内部创建并调用一个 async 函数:
useEffect(() => {
(async function fetchData() {
try {
const res = await fetch('/api/data');
const data = await res.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
})();
}, []);
2. 在 useEffect 内定义并使用单独的 async 函数
该方法清晰区分逻辑和回调调用:
useEffect(() => {
const fetchData = async () => {
const res = await fetch('/api/data');
const result = await res.json();
setData(result);
};
fetchData(); // 在回调内调用
}, []);
最佳实践与注意事项:
- 依赖处理:确保正确处理依赖项(如 [id])。在 useEffect 内定义函数可以减少内存冗余。
- 错误处理:使用 try/catch 包裹异步逻辑以捕获异常。
- 清理函数:如果需要清理,例如取消请求或停止 intervals,在返回的函数中实现(return () => { … }),并确保 async 部分不会干扰。
这些方法遵循 React 官方建议和现代实践,避免直接在 useEffect 外层声明 async,确保组件稳定运行。