【问题标题】:Why is the fetch statement in my react app resulting in two calls?为什么我的反应应用程序中的 fetch 语句会导致两次调用?
【发布时间】:2020-08-27 20:13:56
【问题描述】:

谁能向我解释为什么 fetch 语句会导致 2 个 API 调用? chrome 控制台和开发工具 > 网络选项卡都显示了两个版本。以下是我正在使用的代码。

import React, { useState } from 'react';
import './contact.css';

const App = () => {

  const [contacts, setContacts] = useState([]);

  fetch("https://randomuser.me/api/?results=3")
  .then(response => response.json())
  .then(data => console.log(data));

  return (

    <>
      {
        contacts.map(contact => (
          <ContactCard
            avatar="https://via.placeholder.com/150"
            name={contact.name}
            email={contact.email}
            age={contact.age}
          />
        ))
      }
    </>
  )
};


const ContactCard = props => {

  const [showAge, setShowAge] = useState(false);

  return (
    <div className="contact-card">
      <img src="https://via.placeholder.com/150" alt="profile" />
      <div className="user-details">
        <p>Name: {props.name}</p>
        <p>Email: {props.email}</p>

        <button onClick={() => setShowAge(!showAge)}>{!showAge ? 'Show' : 'Hide'} Age</button>

        {
          showAge && <p>Age: {props.age}</p>
        }

      </div>
    </div>
  );
};

export default App;

【问题讨论】:

  • 看一下调用的类型,是不是一个OPTIONS请求?这是 CORS 的一部分。
  • OPTIONS 是 CORS 飞行前 - 但是,我不明白为什么您的代码会触发飞行前 - 刚刚测试过,它不会是 OPTIONS - 它会有所反应相关
  • App被多次执行,如果想在组件挂载时只调用一次fetch,使用useEffect(() =&gt; fetch(..), [])[]很重要,它保证了函数传递给useEffect 在组件挂载时只运行一次。
  • @Titus 出于某种原因,在最后删除[],似乎仍然有效......就像,现在我只打1个电话!你知道为什么吗?
  • 是的,没错。我之前的评论不完整,当你更新状态(例如调用setContacts)时,该函数也会运行,而不仅仅是在你更新属性时。

标签: javascript reactjs fetch


【解决方案1】:
const App = () => {

  const [contacts, setContacts] = useState([]);
  // the issue is here, each time the component renders this statement will be exectuted
  fetch("https://randomuser.me/api/?results=3")
  .then(response => response.json())
  .then(data => console.log(data));

  // if you want to execute code after component is mounted into dom, use useEffect
  // like this

   useEffect(() => {
        fetch("https://randomuser.me/api/?results=3")
        .then(response => response.json())
        .then(data => console.log(data));
   }, []) // the second param for useEffect is dependencies array, pass an empty array if you want your effect to run only once (which is equivalent to componentDidMount in react class based components)
  return (

    <>
      {
        contacts.map(contact => (
          <ContactCard
            avatar="https://via.placeholder.com/150"
            name={contact.name}
            email={contact.email}
            age={contact.age}
          />
        ))
      }
    </>
  )
};

【讨论】:

  • 虽然,最终删除[] 似乎仍然有效!
  • @Grateful 它会起作用,但它会在每次渲染组件时再次发出网络请求(它将是完全相同的代码,就好像它没有被包装在 useEffect 中一样)
  • 嗯...奇怪!因为一旦我删除了useEffect,它就会返回拨打 2 个电话。然而,如果我继续使用useEffect,它会完美运行......并且 chrome 控制台和网络选项卡只显示 1 个 API 调用,不像以前!
  • 如果可能的话,我真的很想深入了解这个问题!
  • @Grateful 如果你不传递依赖数组,那么每次组件渲染时都会调用 useEffect 中的函数(如果它渲染一次,它将被调用一次),所以要么你的组件现在仅出于其他原因渲染一次,或者您不知道第二个请求 - 假设您确实删除了依赖项数组。这两种情况都是反应文档确认我所说的reactjs.org/docs/hooks-reference.html#useeffect
猜你喜欢
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多