开发者问题收集

ReactJS Fetch 调用一次但发出多个请求

2021-08-28
1086

这是我之前发表的一篇文章的重写,因为我能够使用更简单的例子重现同样的问题。

我使用 npx create-react-app 创建了一个简单的应用程序。我将日志记录逻辑添加到我的 App.js 文件中,如下所示。

import logo from './logo.svg';
import './App.css';

function App() {
  console.log("###? App()");

  const logStuff = () => {
    console.log("###? Logging stuff")
    fetch("https://httpbin.org/post", {
      method: 'POST',
      body: JSON.stringify({error: "hello", message: "there"}),
    })
      .then(() => console.log('###? useLog() response'))
      .catch((error) => {
        console.error('###? Failed to send log with error: ' + error);
      });
  }

  return (
    <div className="App">
      {logStuff()}
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo"/>
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

启动应用程序时,我收到以下日志:

###? App() App.js:5
###? Logging stuff App.js:8
###? useLog() response App.js:9
###? useLog() response

在网络选项卡中,我看到以下内容: 在此处输入图像描述

App() 函数被调用一次。logStuff() 函数被调用一次;但在网络控制台中,我可以看到有两个请求发送到该 URL,我不明白为什么。

1个回答

您已将 logStuff 函数放入 return 语句中,这就是您遇到此行为的原因。请记住,作为良好做法,组件的 return 语句应仅返回 JSX/Components,不应用于任何调用。 如果您在 return 语句内运行函数,则它应返回 JSX/Component。

这是正确的方法。

import './App.css';

function App() {
  console.log("###? App()");

  useEffect(() => {
     logStuff() //this should be regular practice for side effects
  },[]) //useEffect would run once only. If you want to change it on condition then provide other arguments to the array.

  const logStuff = () => {
    console.log("###? Logging stuff")
    fetch("https://httpbin.org/post", {
      method: 'POST',
      body: JSON.stringify({error: "hello", message: "there"}),
    })
      .then(() => console.log('###? useLog() response'))
      .catch((error) => {
        console.error('###? Failed to send log with error: ' + error);
      });
  }

  return (
    <div className="App">
      // {logStuff()} this was the problem, the function was calling on each render
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo"/>
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
Waleed Tariq
2021-08-29