首页 > 解决方案 > 在UseEffect下使用多个设置状态的api调用和一个依赖,如何防止子组件的额外重新渲染?

问题描述

我是 React 世界的新手,我正在努力防止子无状态组件的额外重新渲染,但我的代码没有运气

import React, { useEffect, useState } from "react";
import Lab from "./components/Lab";
import RecentlyCreatedWo from "./components/RecentlyCreatedWo";
import Users from "./components/Users";
import WoCount from "./components/WoCount";
import Wostatus from "./components/Wostatus";
import ApiService from "../../common/utils/ApiService";
import { ApisConfig } from "../../common/configuration/api-config";
import localStorageService from "../../common/utils/localStorageService";
import { Year } from "../../common/utils/Year";
import { Dropdown } from "primereact/dropdown";

export default function Dashboard() {
  const [selectedYear, setSelectedYear] = useState(2021);
  const [woCount, setWoCount] = useState(null);
  const [recentWo, setRecentWo] = useState(null);

  useEffect(() => {
    const api = new ApiService();

    api
      .get(
        ApisConfig.SomeAPi +
          "?someId=" +
          localStorageService.get("userLoginData").someId +
          "&year=" +
          selectedYear
      )
      .then((res) => {
        setWoCount(res);
      });

    api
      .get(
        ApisConfig.someOtherApi+
          "?someId=" +
          localStorageService.get("userLoginData").someId+
          "&year=" +
          selectedYear
      )
      .then((res) => {
        setRecentWo(res);
      });
  }, [selectedYear]);

  const onYearChange = (e) => {
    setSelectedYear(e.value);
  };

  return (
    <div className="admin-dashboard">
      <div className="p-grid">
        <div className="p-col-8">
          <Dropdown
            optionLabel="key"
            value={selectedYear}
            options={Year}
            onChange={onYearChange}
          />
          <Wostatus data={woCount} />
          <RecentlyCreatedWo data={recentWo} />
        </div>
        <div className="p-col-4">
          <WoCount data={woCount} />
          <Lab />
          <Users />
        </div>
      </div>
    </div>
  );
}

我在这里观察到的是,每当年份发生变化时,包括第一次渲染,我的子组件都会收到三次道具,我知道这是因为在 setState 事件和年份变化事件上调用了 useEffect。

我需要的是子组件应该在 api 调用完成并更新道具时重新渲染,实现此功能和优化逻辑的最佳方法是什么?

标签: javascriptreactjs

解决方案


我正在为任何可能像我一样挣扎的新手发布我自己问题的答案。

对于此类问题,react 功能组件具有 useMemo() 钩子,对于我的问题,我已经通过使用这样的钩子来解决它。

   const woStatus = useMemo(
    () => (
      <p>
        <Wostatus data={data.woCount} />
      </p>
    ),
    [data.woCount]
  );

与 JSX 部分相比,我们可以简单地初始化子组件,例如

{Wostatus}

该博客帮助我了解了实际问题以及 react 本身可用的解决方案。

https://kentcdodds.com/blog/usememo-and-usecallback


推荐阅读