如何防止子组件在某人访问页面时首次调用API两次?

huangapple go评论81阅读模式
英文:

How to stop child component from making api call twice for the very first time when someone visit the page

问题

假设我有一个主页,有3个选项卡,分别是"All"、"Sci-fi"和"Comedy"。我在主页中调用子组件,并渲染相应的数据。问题是,当用户首次访问时,默认选中的选项卡是"All"。我的子组件会发起两次相同的 API 请求。如何防止这种情况发生?

import React from 'react';
import ChildComponent from './ChildComponent';

function Home() {
  return (
    <div>
      <h1>Home Component</h1>
      <ChildComponent />
    </div>
  );
}

export default Home;
import React, { useState, useEffect } from 'react';

function ChildComponent() {
  const [data, setData] = useState([]);

  useEffect(() => {
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => setData(data))
      .catch(error => console.error('Error fetching data:', error));
  }, []);

  return (
    <div>
      <h2>Child Component</h2>
      <ul>
        {data.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default ChildComponent;

为了防止子组件重复发起 API 请求,你可以在子组件中使用条件判断来控制是否发起请求。你可以添加一个状态变量来表示是否已经发起了请求,然后在 useEffect 中进行判断。如果请求已经发起过了,就不再重复发起。

import React, { useState, useEffect } from 'react';

function ChildComponent() {
  const [data, setData] = useState([]);
  const [isDataFetched, setIsDataFetched] = useState(false);

  useEffect(() => {
    if (!isDataFetched) {
      fetch('https://api.example.com/data')
        .then(response => response.json())
        .then(data => {
          setData(data);
          setIsDataFetched(true);
        })
        .catch(error => console.error('Error fetching data:', error));
    }
  }, [isDataFetched]);

  return (
    <div>
      <h2>Child Component</h2>
      <ul>
        {data.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default ChildComponent;

通过添加 isDataFetched 状态变量,并在 useEffect 的依赖数组中将其作为依赖项,可以确保只有在 isDataFetched 发生变化时才会发起 API 请求。这样就可以避免重复请求的问题。

英文:

So let say I have one home page with 3 tabs, "All", 'Sci-fi',"Comedy".I am calling the child component in the home page and rendering the respected data. What is happening is that when user visit for the first time tab is selected as "All". My child component is making same api call twice.How to prevent it.

import React from &#39;react&#39;;
import ChildComponent from &#39;./ChildComponent&#39;;

function Home() {
  return (
    &lt;div&gt;
      &lt;h1&gt;Home Component&lt;/h1&gt;
      &lt;ChildComponent /&gt;
    &lt;/div&gt;
  );
}

export default Home;

import React, { useState, useEffect } from &#39;react&#39;;

function ChildComponent() {
  const [data, setData] = useState([]);

  useEffect(() =&gt; {
    fetch(&#39;https://api.example.com/data&#39;)
      .then(response =&gt; response.json())
      .then(data =&gt; setData(data))
      .catch(error =&gt; console.error(&#39;Error fetching data:&#39;, error));
  }, []);

  return (
    &lt;div&gt;
      &lt;h2&gt;Child Component&lt;/h2&gt;
      &lt;ul&gt;
        {data.map(item =&gt; (
          &lt;li key={item.id}&gt;{item.name}&lt;/li&gt;
        ))}
      &lt;/ul&gt;
    &lt;/div&gt;
  );
}

export default ChildComponent;

答案1

得分: 1

React Strict Mode 会渲染组件两次,以检查函数逻辑是否正确实现。

在这种情况下,每次渲染时,API 调用都会不断增加。

你需要实现一个逻辑,在组件被销毁并第二次渲染时清理/销毁 API 调用。

请参考文档 Fixing bugs found by double rendering in development 获取更多信息。

英文:

React Strict Mode renders the component twice to check if the function logic is implemented correctly.

In this scenario, Every time you render, the API calls keeps on increasing.

You need to implement a logic to cleanup/ destroy the API call during the component getting destroyed and rendering for second time.

Refer to the docs Fixing bugs found by double rendering in development for more information.

答案2

得分: 0

我看到了你的问题,我这里有几个解决方案,让我们看看它们是否适用于你的项目:

  • 首先,请确保你已经关闭了ReactJS的StrictMode。
  • 其次,如果你的每个选项卡调用了不同的API,请在主页上创建一个useState。
function Home() {
  const [tabs, setTabs] = useState('TOP_PAGE')
  return (
    <div>
      <h1>Home Component</h1>
      {tabs === 'TOP_PAGE' && <ChildComponentTopPage />}
      {tabs === 'SECOND_PAGE' && <ChildComponentSecondPage />}
    </div>
  );
}
  • 最后,如果每个子组件的API是相同的,我建议将API放在父组件中,然后将props传递给每个子组件。
英文:

I see your issue, I have a few solutions here, let's see if any of them can be applied to your project:

  • Firstly, please make sure you have turned off ReactJS's StrictMode.
  • Secondly, if each tab of yours calls a different API, create a useState on the Home page.

<!-- begin snippet: js hide: false console: false babel: false -->

<!-- language: lang-js -->

function Home() {
  const [tabs, setTabs] = useState(&#39;TOP_PAGE&#39;)
  return (
    &lt;div&gt;
      &lt;h1&gt;Home Component&lt;/h1&gt;
      {tabs === &#39;TOP_PAGE&#39; &amp;&amp; &lt;ChildComponentTopPage /&gt; }
      {tabs === &#39;SECOND_PAGE&#39; &amp;&amp; &lt;ChildComponentSecondPage /&gt; }
    &lt;/div&gt;
  );
}

<!-- end snippet -->

  • Lastly, if the API for each child component is the same, I recommend placing the API in the parent component, and then passing props to each child component.

答案3

得分: 0

尝试在你的 main.jsx 文件中移除 React.StrictMode。你需要将代码从:

<React.StrictMode>
  <App/>
</React.StrictMode>

修改为:

<App/>

因为 React.StrictMode 会出现某种原因导致执行两次。

英文:

Try removing React.Strictmode in your main.jsx.
you would go from:

&lt;React.StrictMode&gt;
&lt;App/&gt;
&lt;/React.StrictMode&gt;

to:
&lt;App/&gt;

, because React.Strictmode executes twice for some reason

huangapple
  • 本文由 发表于 2023年8月9日 16:38:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76865972.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定