reactjs - 如何使 setState 在 useEffect 中工作
问题描述
我正在使用 fetch API 从 API 中获取。
获取结果后,我想将 setState 设置为不工作
的结果,这是获取结果的函数
export const random = (min, max) => Math.floor(Math.random() * (max - min)) + min;
export const getPokemons = async function () {
const pokemon = [];
for (let i = 0; i < 5; i++) {
pokemon.push(fetch(`https://pokeapi.co/api/v2/pokemon/${random(1, 800)}`));
}
return Promise.all(pokemon)
.then((data) => {
const parsedData = [];
data.forEach(async (d) => {
const resJson = await d.json()
parsedData.push(resJson);
});
return parsedData
})
.catch((err) => {
console.log(err);
});
};
导入它的代码
const [stats,setStats] = useState([])
useEffect(()=>{
generateTrio()
},[])
async function generateTrio() {
const gTrio = await getPokemons();
setStats(gTrio)
console.log(stats,gTrio)
}
这里的 stats 是一个空数组,而 gTrio 是必需的结果我想在 setStats
解决方案
问题是双重的:
- 您正在登录
stats
与调用相同的闭包setStats()
。请参阅useState set 方法不立即反映更改,以了解为什么这样做会记录以前的状态。 - 您正在将一个
async
函数传递给回调,forEach()
在外部承诺与最初的空数组解决之后,该函数将数据推送到数组中。有关此反模式的潜在缺陷,请参阅将 async/await 与 forEach 循环一起使用。
你getPokemons()
从你的异步函数返回一个空数组,然后在它用于渲染你的组件后异步填充它。Main
即使您登录stats
了正确的闭包,Chrome 的开发人员控制台输出也会令人困惑,因为它会显示该数组已填充,即使它在记录时为空。请参阅Chrome 的 JavaScript 控制台是否懒于评估数组?有关此开发者控制台行为的更多信息。
一种正确的书写getPokemons()
方式是:
export const getPokemons = () => (
Promise.all(
Array.from({ length: 5 }, async () => {
const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${random(1, 800)}`);
return response.json();
})
)
);
编写Main
组件的正确方法是:
const Wrapper = styled.div``;
const Main = () => {
const [stats, setStats] = useState([]);
useEffect(() => {
const setPokemons = async () => {
setStats(await getPokemons());
};
setPokemons();
}, []);
// console.log(stats);
const names = stats.map(item => (
<p key={item.id}>{item.name}</p>
));
return (
<Wrapper>
{names}
</Wrapper>
);
}
export default Main;
推荐阅读
- java - 如何修复:java中随机数布尔数组的线程“main”java.lang.ArrayIndexOutOfBoundsException中的异常
- c - 检查当前是否在处理时包含文件
- ios - Firestore orderBy 与查询混合不适用于分页
- flutter - Flutter Geolocation后台更新不一致
- tsql - 使用 NOT IN 的 SQL 查询需要很长时间
- mysql - MySQL ERROR 1064 (42000) CREATE TABLE 命令中的子字符串错误
- azure - 不能更改虚拟机规模集的映像类型
- c - 使用函数冒泡排序动态数组
- javascript - vue.js - 如何查看嵌套对象的属性并获取索引?
- macos - imageMagick : 将图像的颜色替换为 tintColor