React:数据在被提取后没有加载



使用MUI和我有一个Select组件(下拉菜单(,我希望使用提取请求中的数据填充其选项。我用一个名为"partners"的数组将数据存储在状态中。最初,partners.map((不起作用,因为partners是空的,所以我想应该等待fetch完成后再进行渲染。这是我的代码,考虑到了这一点:

const [partners, setPartners] = useState([]);
React.useEffect(() => {
fetch('http://localhost:3000/partners')
.then((resp) => resp.json())
.then((data) => setPartners(data));
console.log(partners);
}, []);
if (!partners.length) {
return <Typography>Loading...</Typography>;
}
return ( 
<FormControl>
<>
<Select
onChange={handleFormChange}
>
{partners.map(({ name }) => (
<MenuItem value={name}>{name}</MenuItem>
))}
</Select>
</>
</FormControl>
)

但现在,页面只停留在"正在加载…"并且不会改变。我试过使用!!!如果语句中的partners.length也是,但似乎没有什么区别。useEffect中的console.log(partners(语句只返回一个空数组。问题是,所提取的数据肯定不是空的,所以我不确定发生了什么。console.log((是否可能在fetch或setPartners语句完全完成之前运行?合作伙伴甚至被换了吗?如果是,那么partners.length的检查在任何时间点都不返回True怎么可能呢?

编辑:已修复,请参阅下面的答案

为您创建了这个stackblitzhttps://stackblitz.com/edit/react-mui-5spdkt?file=Hello.js

问题是你试图在setPartners上设置的对象不在列表中,在我的情况下,对于cats api,我需要result.data,就像Cesare说的那样,你的控制台日志在错误的地方

React.useEffect(() => {
fetch('http://localhost:3000/partners')
.then((resp) => resp.json())
.then((data) => setPartners(data));
console.log(partners);  <=== THIS IS EXECUTED AS SOON AS THE FETCH STARTS SO IT'S GONNA BE []
}, []);

如果你想记录提取的数据,你需要记录在最后一个。记得放一个.catch(e => console.error(e)),否则你不会发现任何问题。

如果您想检查partners,它是一个React状态,您需要将console.log(partners)放在React Component函数内,在return语句之前。

const [partners, setPartners] = useState([]);
React.useEffect(() => {
fetch('http://localhost:3000/partners')
.then((resp) => resp.json())
.then((data) => { 
setPartners(data);
console.log("FETCHED DATA:", data); 
})
.catch(e => console.error(e));
}, []);
console.log("RENDERING, PARTNERS:", partners)
if (!partners.length) {
return <Typography>Loading...</Typography>;
}
return ( 
<FormControl>
<>
<Select
onChange={handleFormChange}
>
{partners.map(({ name }) => (
<MenuItem value={name}>{name}</MenuItem>
))}
</Select>
</>
</FormControl>
)

修复了问题,问题是fetch返回的是一个以数组为值的对象,而不是像我假设的那样返回数组本身,所以我认为这把事情搞砸了。我刚刚用setPartners(data[key](替换了setPartners(data(,其中key是映射到值的键。

您可以尽量避免在装饰完成之前返回FormControl组件,如下所示:

const [partners, setPartners] = useState();
const [loading, setLoading] = useState();
React.useEffect(() => {
setLoading(true);
fetch('http://localhost:3000/partners')
.then((resp) => resp.json())
.then((data) => setPartners(data))
.then(setLoading(false));
console.log(partners);
}, []);
return ( 
<FormControl>
{loading ? <Typography>Loading...</Typography>
: <>
<Select
onChange={handleFormChange}
>
{partners.map(({ name }) => (
<MenuItem value={name}>{name}</MenuItem>
))}
</Select>
</> 
}  
</FormControl>
)

最新更新