如何停止在 React 中重新渲染时进行 api 调用?

Unk*_*own 5 javascript api reactjs react-hooks use-effect

在我的主页中,我有类似这样的代码

{selectedTab===0 && <XList allItemList={some_list/>}
{selectedTab===1 && <YList allItemList={some_list2/>}
Run Code Online (Sandbox Code Playgroud)

现在,在 XList 中,我有这样的内容:

{props.allItemList.map(item => <XItem item={item}/>)}
Run Code Online (Sandbox Code Playgroud)

现在,在 XItem 内部,我调用 api 来获取 XItem 的图像。

现在我的问题是,当在主页中,我将选项卡从 0 切换到 1 或 1 切换到 0 时,它再次调用 XItem 中的所有 API。每当我切换选项卡时,它都会再次调用 api。我不想要这样。我已经在 XItem 中使用了 useEffect,并使用 [] 数组作为第二个参数。

我有我的后端代码,我在其中创建了一个 api 来获取 XItem 的图像。API直接返回图像而不是url,所以我不能一次调用所有api。

我需要一些解决方案,以便最大限度地减少 api 调用。感谢帮助。

Dre*_*ese 4

基本问题是,通过选择所选选项卡的方式来安装和卸载组件。重新安装组件必然会重新运行任何useEffect发出网络请求的安装回调并将任何结果存储在本地组件状态中。卸载组件必然会处理组件状态。

{selectedTab === 0 && <XList allItemList={some_list} />}
{selectedTab === 1 && <YList allItemList={some_list2} />}
Run Code Online (Sandbox Code Playgroud)

一种解决方案是将isActiveprop 传递给XListYList,并根据该值设置该值selectedTab。每个组件根据isActiveprop 有条件地渲染其内容。这个想法是保持组件的安装状态,以便它们在最初安装时只获取一次数据。

<XList allItemList={some_list} isActive={selectedTab === 0} />
<YList allItemList={some_list2} isActive={selectedTab === 1} />
Run Code Online (Sandbox Code Playgroud)

例子XList

const XList = ({ allItemList, isActive }) => {
  useEffect(() => {
    // expensive network call
  }, []);

  return isActive 
    ? props.allItemList.map(item => <XItem item={item}/>)
    : null;
};
Run Code Online (Sandbox Code Playgroud)

替代方法包括将 API 请求和状态提升到父组件并作为 props 向下传递。或者使用 React 上下文执行相同的操作并通过上下文提供状态。或者实现/添加到全局状态管理,如 Redux/Thunks。