React 页面请求两次的问题 ?
正在学习 React
不懂为什么用了 useEffect
还会发起两次请求,应该怎么解决?
import { Button } from 'antd-mobile'
import data from './request/page'
import { useState, useEffect } from 'react';
function Page() {
const [list, setList] = useState([])
useEffect(() => {
data().then((e) => {
console.log(e);
})
}, [])
return (
<div>
{list.map(e => e )}
</div>
)
}
export default Page
回复
1个回答
test
2024-07-03
- 这是 React18 才新增的特性。
- 仅在开发模式("development")下,且使用了严格模式("Strict Mode")下会触发。 生产环境("production")模式下和原来一样,仅执行一次。
- 之所以执行两次,是为了模拟立即卸载组件和重新挂载组件。 为了帮助开发者提前发现重复挂载造成的 Bug 的代码。 同时,也是为了以后 React的新功能做铺垫。 未来会给 React 增加一个特性,允许 React 在保留状态的同时,能够做到仅仅对UI部分的添加和删除。 让开发者能够提前习惯和适应,做到组件的卸载和重新挂载之后, 重复执行 useEffect的时候不会影响应用正常运行。
useEffect 除了在组件渲染的时候执行外,在组件卸载的时候也有相关执行操作。 在组件卸载的时候会执行 useEffect 方法的return语句。
useEffect(() => { window.a = 100; return (window.a = 0); }, []);
如上代码段,当组件渲染的时候会执行window.a = 100,当组件卸载的时候会执行window.a = 0。根据你题目中的异步请求可以这样:
useEffect(() => {
let ignore = false;
async function startFetching() {
const json = await fetchTodos(userId);
// 这里执行是异步的,所以第一次执行到此处的时候组件已经被卸载了
// 此时的 ignore 已经被 return 里面的方法置为 true 了
// 所以这里第一次执行的时候不执行 setTodos(json)
// setTodos 其实是在第二次执行的时候才触发
if (!ignore) {
setTodos(json);
}
}
startFetching();
return () => {
ignore = true;
};
}, [userId]);
具体方式参考:
https://juejin.cn/post/7137654077743169573https://juejin.cn/post/7105652180501135367等等等.........
回复
适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容