[英]undefined after setState() (use hook) in Reactjs
I learn react and js myself.我自己学习 react 和 js。 please explain why this situation occurs.
请解释为什么会出现这种情况。 PS: excuse me for the large text, I tried to explain the problem as clearly as possible.
PS:请原谅我的大文字,我试图尽可能清楚地解释问题。 thanks.
谢谢。 Essence of the matter: set the initial state through the hook:
实质:通过钩子设置初始状态:
const [pokemon, setPokemon] = useState({
img: "",
name: "",
types: [],
abilities: [],
moveList: [],
weight: "",
height: "",
description: "",
genus: "",
chanceToCatch: "",
evolutionURL: ""
});
further I make api requests to get information from inside useEffect:此外,我发出 api 请求以从 useEffect 内部获取信息:
useEffect(() => {
const fetchData = async () => {
await Axios({
method: "GET",
url: urlPokemonAPI
})
.then(result => {
const pokemonResponse = result.data;
/* Pokemon Information */
const img = pokemonResponse.sprites.front_default;
const name = pokemonResponse.name;
const weight = Math.round(pokemonResponse.weight / 10);
const height = pokemonResponse.height / 10;
const types = pokemonResponse.types.map(type => type.type.name);
const abilities = pokemonResponse.abilities.map(
ability => ability.ability.name
);
const moveList = pokemonResponse.moves.map(move => move.move.name);
setPokemon(() => {
return {
img: img,
name: name,
weight: weight,
types: types,
abilities: abilities,
moveList: moveList,
height: height
};
});
})
await Axios({
method: "GET",
url: urlPokemonSpecies
}).then(result => {
let description = "";
result.data.flavor_text_entries.forEach(flavor => {
if (flavor.language.name === "en") {
description = flavor.flavor_text;
}
});
let genus = "";
result.data.genera.forEach(genera => {
if (genera.language.name === "en") {
genus = genera.genus;
}
});
const evolutionURL = result.data.evolution_chain.url;
const eggGroups = result.data.egg_groups.map(
egg_group => egg_group.name
);
const chanceToCatch = Math.round(
(result.data.capture_rate * 100) / 255
);
setPokemon(pokemon => {
return {
...pokemon,
description: description,
genus: genus,
chanceToCatch: chanceToCatch,
evolutionURL: evolutionURL,
eggGroups: eggGroups
};
});
});
};
fetchData();
}, [urlPokemonAPI, urlPokemonSpecies]);
The problem arises specifically with eggGroups
(with identical handling of abilities
and types
there is no such problem).这个问题特别出现在
eggGroups
(相同处理abilities
和types
,没有这样的问题)。 And this is what happens when I want to output data to a page as <div> Egg Group: {pokemon.eggGroups} </div>
the data is displayed normally, but as soon as I want to output eggGroups
as well as abilities
and types
separated by commas ( join ( ',')
) - error: TypeError: pokemon.eggGroups is undefined
.这就是当我想将数据作为
<div> Egg Group: {pokemon.eggGroups} </div>
输出到页面时会发生的情况,数据显示正常,但是一旦我想输出eggGroups
以及abilities
和用逗号分隔的types
( join ( ',')
) - 错误: TypeError: pokemon.eggGroups is undefined
。 I decided to check this matter through the console and stuffed this eggGroups
key into the timeout:我决定通过控制台检查这件事并将这个
eggGroups
键塞进超时:
At some point, eggGroups
becomes undefined ... why, I can't understand.在某些时候,
eggGroups
变得未定义......为什么,我无法理解。 But if I set the state separately, like const [egg, setEgg] = useState ([]); setEgg (eggGroups);
但是如果我单独设置状态,比如
const [egg, setEgg] = useState ([]); setEgg (eggGroups);
const [egg, setEgg] = useState ([]); setEgg (eggGroups);
such a problem is not observed.没有观察到这样的问题。 why is this happening?
为什么会这样? everything was fine with
types
and abilities
.一切都很好,
types
和abilities
。 Thank you in advance.先感谢您。
state updater from hooks doesn't merge the state values when updating state, instead it just replaces the old value with new one来自钩子的状态更新器在更新状态时不合并状态值,而是用新值替换旧值
Since you use state updater like由于您使用状态更新程序,例如
setPokemon(() => {
return {
img: img,
name: name,
weight: weight,
types: types,
abilities: abilities,
moveList: moveList,
height: height
};
});
eggGroups
property is lost and hence it becomes undefined. eggGroups
属性丢失,因此它变得未定义。 You need to update it by spreading the previous state values obtained from callback您需要通过传播从回调获得的先前状态值来更新它
setPokemon((prev) => {
return {
...prev
img: img,
name: name,
weight: weight,
types: types,
abilities: abilities,
moveList: moveList,
height: height
};
});
Your code have a problem, this is the proper way to do await with axios, you need to import axios like this您的代码有问题,这是使用 axios 进行等待的正确方法,您需要像这样导入 axios
import axios from 'axios';
the await
should be call with a promise, then it return the data from api like this: await
应该使用承诺调用,然后它从 api 返回数据,如下所示:
const result = await axios.get(urlPokemonAPI);
This is the code snippet with the same logic to your code这是与您的代码具有相同逻辑的代码片段
useEffect(() => {
const fetchData = async () => {
// import axios from 'axios';
try {
const result = await axios.get(urlPokemonAPI);
const pokemon = result.data;
setPokemon({
img: pokemon.sprites.front_default,
name: pokemon.name,
weight: Math.round(pokemon.weight / 10),
types: pokemon.types.map(i => i.type.name),
abilities: pokemon.abilities.map(i => i.ability.name),
moveList: pokemon.moves.map(i => i.move.name),
height: pokemon.height / 10
});
const result2 = await axios.get(urlPokemonSpecies);
const data = result2.data;
let description = "";
data.flavor_text_entries.forEach(i => {
const lang = i.language.name
if (lang === "en") {
description = i.flavor_text;
}
});
let genus = "";
data.genera.forEach(i => {
const lang = i.language.name;
if (lang === "en") {
genus = i.genus;
}
});
setPokemon(pokemon => {
return {
...pokemon,
description,
genus,
chanceToCatch: Math.round((data.capture_rate * 100) / 255),
evolutionURL,
eggGroups: data.egg_groups.map(g => g.name)
};
});
} catch (e) {
console.log(e);
}
};
fetchData();
}, [urlPokemonAPI, urlPokemonSpecies]);
do you see another problem: you call setPokemon two times , let's rewrite it again:你看到另一个问题:你调用 setPokemon 两次,我们再重写一遍:
useEffect(() => {
const fetchData = async () => {
// import axios from 'axios';
try {
const result = await axios.get(urlPokemonAPI);
const data1 = result.data;
const result2 = await axios.get(urlPokemonSpecies);
const data2 = result2.data;
function resolveDescription(data) {
let description = "";
data.flavor_text_entries.forEach(i => {
const lang = i.language.name
if (lang === "en") {
description = i.flavor_text;
}
});
return description;
}
function resolveGenus(data) {
let genus = "";
data.genera.forEach(i => {
const lang = i.language.name;
if (lang === "en") {
genus = i.genus;
}
});
return genus;
}
setPokemon({
img: data1.sprites.front_default,
name: data1.name,
weight: Math.round(data1.weight / 10),
types: data1.types.map(i => i.type.name),
abilities: data1.abilities.map(i => i.ability.name),
moveList: data1.moves.map(i => i.move.name),
height: data1.height / 10,
description: resolveDescription(data2),
genus: resolveGenus(data2),
chanceToCatch: Math.round((data2.capture_rate * 100) / 255),
evolutionURL: data2.evolution_chain.url,
eggGroups: data2.egg_groups.map(g => g.name)
});
} catch (e) {
console.log(e);
}
};
fetchData();
}, [urlPokemonAPI, urlPokemonSpecies]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.