0

在过去的一个小时里,我一直在用头撞我的桌子,试图弄清楚为什么下面的代码只显示加载微调器,并且即使我可以看到控制台中记录的数据,也永远不会更新以显示实际数据,所以我知道实际上正在获取数据。

应该发生的是,页面将在第一次检索数据时显示微调器加载器,然后在useSWR完成获取数据后,页面将重新渲染以显示数据。数据最终会像地球一样显示出来,但作为原型,我只是用.map. 该页面也不应该再次显示微调器。

我认为我的问题可能与调用函数在最后更新钩子导致整个页面重新渲染有关,尽管我不确定,如果是这种情况,我不知道如何考虑到 SWR 如何自发地重新获取数据,我会做这项工作。

这是主文件:

import { useEffect, useState } from "react";
import Navbar from "@components/navbar";
import Globe from "@/components/interest-globes/globe";

import usePercentages from "@/components/interest-globes/globe-percentages";
const globeName = "primary";

const App = () => {
  const [globePercentages, setGlobePercentages] = useState([]);
  const [isFirstLoad, setFirstLoad] = useState(false);
  const [isLoading, setLoading] = useState(false);
  const [isError, setError] = useState();

  useEffect(() => {
    setFirstLoad(true);
  }, []);

  let {
    globePercentages: newGlobePercentages,
    isLoading: newLoadingState,
    isError: newErrorState,
  } = usePercentages(globeName);

  console.log(newGlobePercentages, newLoadingState, newErrorState);

  useEffect(() => {
    updateGlobe();
  }, [newGlobePercentages, newLoadingState, newErrorState]);

  const updateGlobe = () => {
    if (
      isFirstLoad &&
      (newGlobePercentages !== null || newGlobePercentages !== "undefined")
    ) {
      setFirstLoad(false);
    } else if (newLoadingState || !newGlobePercentages) {
      setLoading(true);
      return;
    } else if (newErrorState) {
      setError(newErrorState);
      return;
    }

    setGlobePercentages(newGlobePercentages);
  };

  return (
    <div>
      <Navbar />
      <div className="container-md">
        <h1>The percentages are:</h1>
        <br />
        <Globe
          globePercentages={globePercentages}
          isLoading={isLoading}
          isError={isError}
        />
        {/* <Globe props={{ globePercentages, isLoading, isError }} /> */}
        <br />
      </div>
    </div>
  );
};

export default App;

这是地球组件:

import Loading from "@components/loading";
import Error from "@components/error";

const Globe = ({ globePercentages, isLoading, isError }) => {
// const Globe = ({ props }) => {
//   let { globePercentages, isLoading, isError } = props;

  if (isLoading) {
    return <Loading/>
  }
  else if (isError) {
    return <Error/>
  }

  return (
    <div>
      {globePercentages.map((interest) => (
        <div key={interest.name}>
          <h2>Name: {interest.name}</h2>
          <h4>Globe Percentage: {interest.globePercentage}%</h4>
          <br />
        </div>
      ))}
    </div>
  );
};

export default Globe;

这是使用百分比:

import { useEffect } from "react";
import useSWR from "swr";
import fetcher from "@components/fetcher";

const usePercentages = (globeName) => {
  const url = `/api/v1/interest-globes/${globeName}/get-globe-percentages`;
  let { data, error } = useSWR(url, fetcher, { refreshInterval: 1000 });

  return {
    globePercentages: data,
    isLoading: !error && !data,
    isError: error,
  };
};

export default usePercentages;
4

1 回答 1

1

如果你把你的钩子移动到你的Globe组件中,一切都会变得如此简单:

const App = () => {

  return (
    <div>
      <Navbar />
      <div className="container-md">
        <h1>The percentages are:</h1>
        <br />
        <Globe globeName={'primary'}/>
        <br />
      </div>
    </div>
  );
};

export default App;
const Globe = ({globeName}) => {

  const lastPercentages = useRef(null);

  const {
    globePercentages,
    isLoading,
    isError,
  } = usePercentages(globeName);

  // only show the loader if isLoading AND lastPercentages is false-y
  if (isLoading && !lastPercentages.current) {
    return <Loading/>
  }

  if (isError) {
    return <Error/>
  } 
  
  lastPercentages.current = globePercentages ?? lastPercentages.current;

  return (
    <div>
      {lastPercentages.current.map((interest) => (
        <div key={interest.name}>
          <h2>Name: {interest.name}</h2>
          <h4>Globe Percentage: {interest.globePercentage}%</h4>
          <br />
        </div>
      ))}
    </div>
  );  

}

真理的源泉,globePercentages来自于钩子isLoadingisErrorusePercentages。感觉很复杂,因为您将这些数据复制到新的状态变量中,然后要求您保持它们同步。它们旨在用作事实的来源,不要在您自己的状态变量中重新创建它们。

于 2021-05-31T15:53:36.130 回答