【发布时间】:2021-08-18 21:31:27
【问题描述】:
我设置了以下示例 Next.js 应用程序来测试我在对 API 端点的 useSWR 调用中包含的变量使用 toISOString() JavaScript 函数时看到的问题:
下面是pages/user/[id].tsx 的代码,其中toISOString() 被调用:
import NextLink from "next/link";
import {
Link,
Flex,
Box,
Text,
SimpleGrid,
Heading,
Alert
} from "@chakra-ui/core";
import useSWR from "swr";
import { useRouter } from "next/router";
type Data = {
id: string;
name: string;
email: string;
};
const fetcher = async (url: string) => {
const res = await fetch(url);
if (!res.ok) {
throw Error("Yo that's NOT OK!!!");
}
const data: Data = await res.json();
return data;
};
const UserData = () => {
const router = useRouter();
const { id } = router.query;
const today = new Date();
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);
const ssd = yesterday.toISOString(); // TROUBLE
// const ssd = "2021-08-16T19:27:51.630Z"; //fine
const result = useSWR(`/api/user/${id}/${ssd}`, fetcher, {
revalidateOnFocus: false
});
const data: Data = result.data;
const error: Error = result.error;
if (error) {
return <Alert status="error">Loading failed: {error.message}</Alert>;
}
if (!data) {
return <Alert status="info">Loading...</Alert>;
}
return (
<SimpleGrid columns={2} width="2xs" spacingY={4}>
<Text fontWeight="bold" marginRight={4}>
UserID
</Text>
<Text>{data.id}</Text>
<Text fontWeight="bold" marginRight={4}>
Name
</Text>
<Text>{data.name}</Text>
<Text fontWeight="bold" marginRight={4}>
Email
</Text>
<Text>{data.email}</Text>
</SimpleGrid>
);
};
const UserPage = () => {
return (
<Box>
<Flex flexDirection="column" alignItems="center">
<Heading marginY="2rem">User</Heading>
<UserData />
<NextLink href="/">
<Link marginY="2rem">
<Text fontStyle="italic">Go back home</Text>
</Link>
</NextLink>
</Flex>
</Box>
);
};
export default UserPage;
pages/user/[id].tsx 的第 34 行是调用 toISOString() 并触发多个 API 调用的位置,如浏览器控制台所示(控制台语句添加到 /pages/api/user/[...params].ts 第 7 行 - 请参阅下面的完整示例代码)。 toISOString() 函数似乎就像 Next.js 中的 useState 函数一样,因此触发了似乎不会停止的 API 调用。
关于如何使用toISOString() 并且不让它通过useSWR() 触发多个API 调用的任何想法?
以下是完整示例应用的副本:
【问题讨论】:
-
请包含所涉及代码的minimal reproducible example,而不是让人们来回访问您的代码框,如果他们甚至可以访问它。见How to Ask。
-
@w-patrick-gale,请查看答案,如果它解决了您的问题,请告诉我们
-
感谢@AppCity 的回答。 HM,我在问题中嵌入了示例代码(谢谢,如果我应该包含更多内容,请告诉我)。我仍然不明白为什么 ISOString 函数需要在运行 SWR 的函数之外。在我的生产代码中,我在主导出函数中有 ISOString 函数和 SWR 代码。当我将 SWR 代码从主导出函数中移出并放入一个单独的函数(例如答案中的 UserData)并传入 ISOString 值时,这解决了无限 API 调用。但是为什么首先要进行无限的 API 调用呢?