在过去的一个小时里,我一直在用头撞我的桌子,试图弄清楚为什么下面的代码只显示加载微调器,而从不更新以显示实际数据,即使我可以看到记录在控制台中的数据,所以我知道实际上正在获取数据。
应该发生的是,页面将在第一次检索数据时显示一个微调加载器,然后在 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;
答案 0 :(得分: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
、isLoading
和 isError
的真实来源来自 usePercentages
钩子。感觉很复杂,因为您将这些数据复制到新的状态变量中,然后要求您保持它们同步。它们旨在用作事实来源,请勿在您自己的状态变量中重新创建它们。