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

image.png

阅读 3.1k
2 个回答
  1. 这是 React18 才新增的特性。
  2. 仅在开发模式("development")下,且使用了严格模式("Strict Mode")下会触发。
    生产环境("production")模式下和原来一样,仅执行一次。
  3. 之所以执行两次,是为了模拟立即卸载组件和重新挂载组件。
    为了帮助开发者提前发现重复挂载造成的 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/7137654077743169573
https://juejin.cn/post/7105652180501135367
等等等.........

请把 请求截图发上来

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题