所以,我正在温习 React,并制作了一些愚蠢的网络应用程序进行练习,但我遇到了一个我似乎无法弄清楚的问题。
我有一个自定义挂钩 useGetRequest,它调用提供给它的 api 端点并检索数据。我有一个状态变量来跟踪它是否正在加载、已加载或错误。我将此加载状态传递给另一个钩子,然后将其传递给组件。问题是,当它到达组件时,loadingState 变量在每个点都是未定义的。我可以在两个钩子中跟踪状态已更新,但在组件收到状态时未更新。这是我的代码:
import {useCallback, useState} from "react";
import loadingStatus from "../helpers/loadingStatus"
const useGetRequest = (url) => {
const [loadingState, setLoadingState] = useState(loadingStatus.isLoading);
const get = useCallback(async () => {
console.log(loadingState);
setLoadingState(loadingStatus.isLoading);
try {
const rsp = await fetch(url);
const result = await rsp.json();
setLoadingState(loadingStatus.loaded);
return result;
} catch {
setLoadingState(loadingStatus.hasErrored);
}
}, [url]);
return {get, loadingState};
}
export default useGetRequest;
我的愚蠢练习应用程序适用于 TTRPG,只是为了了解此 useWeapons 挂钩的一些背景:
import {useEffect, useState} from "react";
import useGetRequest from "@/hooks/useGetRequest";
const useWeapons = () => {
const [weapons, setWeapons] = useState([]);
const {get, loadingState } = useGetRequest("/api/weapons");
useEffect(() => {
const fetchWeapons = async () => {
const weapons = await get();
console.log(loadingState);
setWeapons(weapons);
};
fetchWeapons();
}, [get]);
return [weapons, setWeapons, loadingState];
}
export default useWeapons;
这是创建我的表格视图的组件:
import WeaponRow from "@/components/WeaponRow";
import useWeapons from "@/hooks/useWeapons";
import loadingStatus from "@/helpers/loadingStatus";
import LoadingIndicator from "@/components/loadingIndicator";
const WeaponList = () => {
const { weapons, setWeapons, loadingState } = useWeapons();
const addWeapon = () => {
setWeapons([
...weapons,
{
id: 2,
name: "Blaster pistol",
skill: "Ranged (Light)",
damage: 6,
critical: 3,
range: "medium",
encum: 1,
hp: 3,
price: 400,
rarity: 4,
special: "Stun setting",
description: "Most spacers carry standard blaster pistols. They pack enough punch to penetrate plastoid armor, have decent range, and are light enough to carry around at all times. Most scoundrels also appreciate the gunslinger-style look of a well-used blaster on their hip. \nSpacefarers who often have to fight aboard ship carry these weapons since the blast is effective against many types of armor, but isn't powerful enough to breach the hull of most vessels. ",
models: "BlasTech DH-17 Blaster, BlasTech SE-14 and SE-14C Blaster Pistol",
image: "blasterPistol"
}
]);
}
if(loadingState !== loadingStatus.loaded) {
console.log(loadingState);
return <LoadingIndicator loadingState={loadingState}/>;
}
else
return(
<>
<div className={"row mb-2"}>
<h5 className={"themeFontColor text-center"}>
Available Weapons
</h5>
</div>
<table className={"table table-hover"}>
<thead>
<tr>
<th>Name</th>
<th>Skill</th>
<th>Dam</th>
<th>Crit</th>
<th>Range</th>
<th>Encum</th>
<th>HP</th>
<th>Price</th>
<th>Rarity</th>
<th>Special</th>
</tr>
</thead>
<tbody>
{weapons.map((w) => (
<WeaponRow key={w.id} weapon={w} />
))}
</tbody>
</table>
<button className={"btn btn-primary"} onClick={addWeapon}>
Add
</button>
</>
)
};
export default WeaponList;
我确信我在这里遗漏了一些明显愚蠢的部分,并且在弄乱了几个小时后我只是看不到它。
作为此处的快速编辑,绕过 useWeapon 挂钩并直接在组件中调用 useGetRequest 挂钩是可行的。我想,要么是我不了解嵌套钩子,要么是我的第二个钩子有问题。
@David 在我发布此内容后 5 分钟内发现,我的问题是我的第二个钩子中的拼写错误。我正在返回这个:
[weapons, setWeapons, loadingState]
当我应该归还这个时:
{weapons, setWeapons, loadingState}
谢谢你我的朋友。