SWR 卡在加载状态。即使在请求完成后
SWR stuck in loading state. Even after request is completed
我正在使用 SWR 来完成一个简单的 API 请求,但是在我刚刚完成格式化后 API 我想要的 SWR 现在卡在了加载状态,我很困惑为什么我尝试了一些不同的方法,但 none 尚未解决我的问题。
我知道 API 的响应包含一个 JSON 对象,在代码中我确实尝试转换为 JavaScript 对象,但它似乎无济于事。
在 fetcher
中,我将其设置为 return 数据并挖掘 JSON 对象,如果我从 return
中删除 British_Roles
然后 Next.js 会 return 一个错误,说地图不是函数。
感觉这可能是我遗漏的一个简单问题,但请记住我不是专业人士。任何帮助都会被大大接受
import {
Table,
TableCaption,
Thead,
Tr,
Th,
Tbody,
Td,
Tfoot,
Text,
Accordion,
AccordionItem,
AccordionButton,
AccordionPanel,
AccordionIcon,
Box,
Center,
Stack,
Heading,
VStack,
} from "@chakra-ui/react";
import useSWR from "swr";
import axios from "axios";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
const fetcher = async (url, key) => {
const res = await axios.get(url, {
headers: {
Authorization: `Bearer ${key}`,
"Content-Type": "application/json",
},
});
return res.data.data.attributes;
};
export const InsurgentDropdown = () => {
var key = process.env.REACT_APP_API_KEY;
var key =
"xxx";
const { data, error } = useSWR(
["https://api.squadkitresearch.net/api/britishes/1?populate=%2A", key],
fetcher
);
if (error)
return console.log(error), (<div>Failed to load {error.message}</div>);
if (!data) return <div>Loading...</div>;
// using roles or data in the map below makes no difference
return (
<>
{data.map((faction) => (
<VStack p="5">
<Accordion allowToggle>
<AccordionItem>
<AccordionButton>
<Box flex="1" textAlign="left">
<Heading fontSize="20px">
{faction.role_name || "Data Error"}
</Heading>
</Box>
<AccordionIcon />
</AccordionButton>
<AccordionPanel>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</AccordionPanel>
</AccordionItem>
</Accordion>
<Accordion allowToggle>
<AccordionItem>
<h2>
<AccordionButton>
<Box flex="1" textAlign="left">
<Heading fontSize="20px">
{faction.role_name || "Data Error"}
</Heading>
</Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel pb={4}>
<Table variant="striped" colorScheme="teal">
<TableCaption fontSize="15px">
{faction.role_name || "Squad Kit Weapon Name"} Role
Information
</TableCaption>
<Thead>
<Tr>
<Th fontSize="20px">Primary Weapon</Th>
<Th fontSize="20px">Magazine Size</Th>
<Th fontSize="20px">Weapon Sights Type</Th>
<Th fontSize="20px">Weapon Firing Modes</Th>
<Th isNumeric fontSize="20px">
Magazine Count
</Th>
</Tr>
</Thead>
<Tbody>
<Tr>
<Td>{faction.Primary || "Data Error"}</Td>
<Td>
{faction.Primary_Magazine_Round_Amount ||
"Data Error"}
</Td>
<Td>{faction.Primary_Sights || "Data Error"}</Td>
<Td>{faction.Primary_Firing_Modes || "Data Error"}</Td>
<Td>
{faction.Primary_Magazine_Amount || "Data Error"}
</Td>
</Tr>
</Tbody>
<Tr>
<Th fontSize="20px">Secondary Weapon</Th>
<Th fontSize="20px">Magazine Size</Th>
<Th fontSize="20px">Weapon Sights Type</Th>
<Th fontSize="20px">Weapon Firing Modes</Th>
<Th isNumeric fontSize="20px">
Magazine Count
</Th>
</Tr>
</Table>
</AccordionPanel>
</AccordionItem>
</Accordion>
</VStack>
))}
</>
);
};
// API 响应
{
"data": {
"id": 1,
"attributes": {
"Role_Name": "British Squad Lead (Iron Sights)",
"createdAt": "2022-02-05T05:55:35.926Z",
"updatedAt": "2022-02-05T05:55:38.194Z",
"publishedAt": "2022-02-05T05:55:38.184Z",
"locale": "en",
"British_Roles": [
{
"id": 1,
"role_name": "British Squad Lead (Iron Sights)",
"Primary": "L85A2 + Foregrip + Bipod",
"Primary_Sights": "Iron Sights",
"Primary_Firing_Modes": "Auto/Single",
"Primary_Magazine_Amount": 7,
"Primary_Magazine_Round_Amount": 30,
"Secondary": "L131A1",
"Secondary_Sights": "Iron Sights",
"Secondary_Firing_Modes": "Single",
"Secondary_Magazine_Amount": 2,
"Secondary_Magazine_Round_Amount": null,
"Secondary_Knife": "SA80 Bayonet"
}
],
"British_Role_Extras": [
{
"id": 1,
"__component": "loadouts.third-slot",
"Third_Slot_Item": "L109A1 Fragmentation Grenade",
"Item_Amount": 2
},
{
"id": 1,
"__component": "loadouts.forth-slot",
"Forth_Slot_Item": "L132A1 White Smoke Grenade",
"Item_Amount": 2
},
{
"id": 2,
"__component": "loadouts.forth-slot",
"Forth_Slot_Item": "L152A1 Orange Smoke Grenade",
"Item_Amount": 1
},
{
"id": 3,
"__component": "loadouts.forth-slot",
"Forth_Slot_Item": "L152A1 Yellow Smoke Grenade",
"Item_Amount": 1
},
{
"id": 1,
"__component": "loadouts.fifth-slot",
"Fith_Slot_Item": "Field Dressing",
"Item_Amount": 2
},
{
"id": 1,
"__component": "loadouts.sixth-slot",
"Sixth_Slot_Item": "Field Binoculars",
"Item_Amount": 1
},
{
"id": 2,
"__component": "loadouts.sixth-slot",
"Sixth_Slot_Item": "Rally Point",
"Item_Amount": 1
}
],
"localizations": {
"data": []
}
}
},
"meta": {}
}
您缺少 attributes
对象。尝试改变
return res.data.British_Roles;
到
return res.data.attributes.British_Roles;
以后,请始终尝试通过在 return 值之前添加 console.log 来进行调试,以确保您 return 使用正确的值。
const fetcher = async (url, key) => {
const res = await axios.get(url, {
headers: {
Authorization: `Bearer ${key}`,
"Content-Type": "application/json",
},
});
//so you know the error occurs here due to missing 'attributes'
console.log(res.data.attributes.British_Roles)
return res.data.attributes.British_Roles;
};
const response = {
"data": {
"id": 1,
"attributes": {
"Role_Name": "British Squad Lead (Iron Sights)",
"createdAt": "2022-02-05T05:55:35.926Z",
"updatedAt": "2022-02-05T05:55:38.194Z",
"publishedAt": "2022-02-05T05:55:38.184Z",
"locale": "en",
"British_Roles": [
{
"id": 1,
"role_name": "British Squad Lead (Iron Sights)",
"Primary": "L85A2 + Foregrip + Bipod",
"Primary_Sights": "Iron Sights",
"Primary_Firing_Modes": "Auto/Single",
"Primary_Magazine_Amount": 7,
"Primary_Magazine_Round_Amount": 30,
"Secondary": "L131A1",
"Secondary_Sights": "Iron Sights",
"Secondary_Firing_Modes": "Single",
"Secondary_Magazine_Amount": 2,
"Secondary_Magazine_Round_Amount": null,
"Secondary_Knife": "SA80 Bayonet"
}
],
"British_Role_Extras": [
{
"id": 1,
"__component": "loadouts.third-slot",
"Third_Slot_Item": "L109A1 Fragmentation Grenade",
"Item_Amount": 2
},
{
"id": 1,
"__component": "loadouts.forth-slot",
"Forth_Slot_Item": "L132A1 White Smoke Grenade",
"Item_Amount": 2
},
{
"id": 2,
"__component": "loadouts.forth-slot",
"Forth_Slot_Item": "L152A1 Orange Smoke Grenade",
"Item_Amount": 1
},
{
"id": 3,
"__component": "loadouts.forth-slot",
"Forth_Slot_Item": "L152A1 Yellow Smoke Grenade",
"Item_Amount": 1
},
{
"id": 1,
"__component": "loadouts.fifth-slot",
"Fith_Slot_Item": "Field Dressing",
"Item_Amount": 2
},
{
"id": 1,
"__component": "loadouts.sixth-slot",
"Sixth_Slot_Item": "Field Binoculars",
"Item_Amount": 1
},
{
"id": 2,
"__component": "loadouts.sixth-slot",
"Sixth_Slot_Item": "Rally Point",
"Item_Amount": 1
}
],
"localizations": {
"data": []
}
}
},
"meta": {}
}
console.log(response.data.attributes.British_Roles)
我正在使用 SWR 来完成一个简单的 API 请求,但是在我刚刚完成格式化后 API 我想要的 SWR 现在卡在了加载状态,我很困惑为什么我尝试了一些不同的方法,但 none 尚未解决我的问题。
我知道 API 的响应包含一个 JSON 对象,在代码中我确实尝试转换为 JavaScript 对象,但它似乎无济于事。
在 fetcher
中,我将其设置为 return 数据并挖掘 JSON 对象,如果我从 return
中删除 British_Roles
然后 Next.js 会 return 一个错误,说地图不是函数。
感觉这可能是我遗漏的一个简单问题,但请记住我不是专业人士。任何帮助都会被大大接受
import {
Table,
TableCaption,
Thead,
Tr,
Th,
Tbody,
Td,
Tfoot,
Text,
Accordion,
AccordionItem,
AccordionButton,
AccordionPanel,
AccordionIcon,
Box,
Center,
Stack,
Heading,
VStack,
} from "@chakra-ui/react";
import useSWR from "swr";
import axios from "axios";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
const fetcher = async (url, key) => {
const res = await axios.get(url, {
headers: {
Authorization: `Bearer ${key}`,
"Content-Type": "application/json",
},
});
return res.data.data.attributes;
};
export const InsurgentDropdown = () => {
var key = process.env.REACT_APP_API_KEY;
var key =
"xxx";
const { data, error } = useSWR(
["https://api.squadkitresearch.net/api/britishes/1?populate=%2A", key],
fetcher
);
if (error)
return console.log(error), (<div>Failed to load {error.message}</div>);
if (!data) return <div>Loading...</div>;
// using roles or data in the map below makes no difference
return (
<>
{data.map((faction) => (
<VStack p="5">
<Accordion allowToggle>
<AccordionItem>
<AccordionButton>
<Box flex="1" textAlign="left">
<Heading fontSize="20px">
{faction.role_name || "Data Error"}
</Heading>
</Box>
<AccordionIcon />
</AccordionButton>
<AccordionPanel>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</AccordionPanel>
</AccordionItem>
</Accordion>
<Accordion allowToggle>
<AccordionItem>
<h2>
<AccordionButton>
<Box flex="1" textAlign="left">
<Heading fontSize="20px">
{faction.role_name || "Data Error"}
</Heading>
</Box>
<AccordionIcon />
</AccordionButton>
</h2>
<AccordionPanel pb={4}>
<Table variant="striped" colorScheme="teal">
<TableCaption fontSize="15px">
{faction.role_name || "Squad Kit Weapon Name"} Role
Information
</TableCaption>
<Thead>
<Tr>
<Th fontSize="20px">Primary Weapon</Th>
<Th fontSize="20px">Magazine Size</Th>
<Th fontSize="20px">Weapon Sights Type</Th>
<Th fontSize="20px">Weapon Firing Modes</Th>
<Th isNumeric fontSize="20px">
Magazine Count
</Th>
</Tr>
</Thead>
<Tbody>
<Tr>
<Td>{faction.Primary || "Data Error"}</Td>
<Td>
{faction.Primary_Magazine_Round_Amount ||
"Data Error"}
</Td>
<Td>{faction.Primary_Sights || "Data Error"}</Td>
<Td>{faction.Primary_Firing_Modes || "Data Error"}</Td>
<Td>
{faction.Primary_Magazine_Amount || "Data Error"}
</Td>
</Tr>
</Tbody>
<Tr>
<Th fontSize="20px">Secondary Weapon</Th>
<Th fontSize="20px">Magazine Size</Th>
<Th fontSize="20px">Weapon Sights Type</Th>
<Th fontSize="20px">Weapon Firing Modes</Th>
<Th isNumeric fontSize="20px">
Magazine Count
</Th>
</Tr>
</Table>
</AccordionPanel>
</AccordionItem>
</Accordion>
</VStack>
))}
</>
);
};
// API 响应
{
"data": {
"id": 1,
"attributes": {
"Role_Name": "British Squad Lead (Iron Sights)",
"createdAt": "2022-02-05T05:55:35.926Z",
"updatedAt": "2022-02-05T05:55:38.194Z",
"publishedAt": "2022-02-05T05:55:38.184Z",
"locale": "en",
"British_Roles": [
{
"id": 1,
"role_name": "British Squad Lead (Iron Sights)",
"Primary": "L85A2 + Foregrip + Bipod",
"Primary_Sights": "Iron Sights",
"Primary_Firing_Modes": "Auto/Single",
"Primary_Magazine_Amount": 7,
"Primary_Magazine_Round_Amount": 30,
"Secondary": "L131A1",
"Secondary_Sights": "Iron Sights",
"Secondary_Firing_Modes": "Single",
"Secondary_Magazine_Amount": 2,
"Secondary_Magazine_Round_Amount": null,
"Secondary_Knife": "SA80 Bayonet"
}
],
"British_Role_Extras": [
{
"id": 1,
"__component": "loadouts.third-slot",
"Third_Slot_Item": "L109A1 Fragmentation Grenade",
"Item_Amount": 2
},
{
"id": 1,
"__component": "loadouts.forth-slot",
"Forth_Slot_Item": "L132A1 White Smoke Grenade",
"Item_Amount": 2
},
{
"id": 2,
"__component": "loadouts.forth-slot",
"Forth_Slot_Item": "L152A1 Orange Smoke Grenade",
"Item_Amount": 1
},
{
"id": 3,
"__component": "loadouts.forth-slot",
"Forth_Slot_Item": "L152A1 Yellow Smoke Grenade",
"Item_Amount": 1
},
{
"id": 1,
"__component": "loadouts.fifth-slot",
"Fith_Slot_Item": "Field Dressing",
"Item_Amount": 2
},
{
"id": 1,
"__component": "loadouts.sixth-slot",
"Sixth_Slot_Item": "Field Binoculars",
"Item_Amount": 1
},
{
"id": 2,
"__component": "loadouts.sixth-slot",
"Sixth_Slot_Item": "Rally Point",
"Item_Amount": 1
}
],
"localizations": {
"data": []
}
}
},
"meta": {}
}
您缺少 attributes
对象。尝试改变
return res.data.British_Roles;
到
return res.data.attributes.British_Roles;
以后,请始终尝试通过在 return 值之前添加 console.log 来进行调试,以确保您 return 使用正确的值。
const fetcher = async (url, key) => {
const res = await axios.get(url, {
headers: {
Authorization: `Bearer ${key}`,
"Content-Type": "application/json",
},
});
//so you know the error occurs here due to missing 'attributes'
console.log(res.data.attributes.British_Roles)
return res.data.attributes.British_Roles;
};
const response = {
"data": {
"id": 1,
"attributes": {
"Role_Name": "British Squad Lead (Iron Sights)",
"createdAt": "2022-02-05T05:55:35.926Z",
"updatedAt": "2022-02-05T05:55:38.194Z",
"publishedAt": "2022-02-05T05:55:38.184Z",
"locale": "en",
"British_Roles": [
{
"id": 1,
"role_name": "British Squad Lead (Iron Sights)",
"Primary": "L85A2 + Foregrip + Bipod",
"Primary_Sights": "Iron Sights",
"Primary_Firing_Modes": "Auto/Single",
"Primary_Magazine_Amount": 7,
"Primary_Magazine_Round_Amount": 30,
"Secondary": "L131A1",
"Secondary_Sights": "Iron Sights",
"Secondary_Firing_Modes": "Single",
"Secondary_Magazine_Amount": 2,
"Secondary_Magazine_Round_Amount": null,
"Secondary_Knife": "SA80 Bayonet"
}
],
"British_Role_Extras": [
{
"id": 1,
"__component": "loadouts.third-slot",
"Third_Slot_Item": "L109A1 Fragmentation Grenade",
"Item_Amount": 2
},
{
"id": 1,
"__component": "loadouts.forth-slot",
"Forth_Slot_Item": "L132A1 White Smoke Grenade",
"Item_Amount": 2
},
{
"id": 2,
"__component": "loadouts.forth-slot",
"Forth_Slot_Item": "L152A1 Orange Smoke Grenade",
"Item_Amount": 1
},
{
"id": 3,
"__component": "loadouts.forth-slot",
"Forth_Slot_Item": "L152A1 Yellow Smoke Grenade",
"Item_Amount": 1
},
{
"id": 1,
"__component": "loadouts.fifth-slot",
"Fith_Slot_Item": "Field Dressing",
"Item_Amount": 2
},
{
"id": 1,
"__component": "loadouts.sixth-slot",
"Sixth_Slot_Item": "Field Binoculars",
"Item_Amount": 1
},
{
"id": 2,
"__component": "loadouts.sixth-slot",
"Sixth_Slot_Item": "Rally Point",
"Item_Amount": 1
}
],
"localizations": {
"data": []
}
}
},
"meta": {}
}
console.log(response.data.attributes.British_Roles)