Javascript Reactjs中setState()之后未定义(使用钩子)
我学会了自己做出反应。请解释为什么会出现这种情况。请原谅我的文章太多,我尽量把问题解释清楚。谢谢本质:通过钩子设置初始状态:Javascript Reactjs中setState()之后未定义(使用钩子),javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我学会了自己做出反应。请解释为什么会出现这种情况。请原谅我的文章太多,我尽量把问题解释清楚。谢谢本质:通过钩子设置初始状态: const [pokemon, setPokemon] = useState({ img: "", name: "", types: [], abilities: [], moveList: [], weight: "", height: "", description: "", genus: "
const [pokemon, setPokemon] = useState({
img: "",
name: "",
types: [],
abilities: [],
moveList: [],
weight: "",
height: "",
description: "",
genus: "",
chanceToCatch: "",
evolutionURL: ""
});
此外,我还请求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]);
问题特别出现在eggGroups
上(对于能力
和类型
的处理相同,则不存在此类问题)。这就是当我想将数据输出到一个页面,作为egggroup:{pokemon.eggGroups}
时,数据会正常显示,但只要我想输出eggGroups
以及能力
和类型
并用逗号(join(',')
)-错误:TypeError:pokemon.eggGroups未定义
。我决定通过控制台检查此事,并将此eggGroups
键插入超时:
在某一点上,
eggGroups
变得未定义。。。为什么,我不明白。但是如果我单独设置状态,比如const[egg,setEgg]=useState([]);卵(卵群)代码>未观察到此类问题。为什么会这样?使用类型
和能力
一切都很好。提前谢谢。钩子中的状态更新程序在更新状态时不会合并状态值,而是用新值替换旧值
因为您使用的状态更新程序像
setPokemon(() => {
return {
img: img,
name: name,
weight: weight,
types: types,
abilities: abilities,
moveList: moveList,
height: height
};
});
eggGroups
属性丢失,因此它变得未定义。您需要通过传播从回调中获得的先前状态值来更新它
setPokemon((prev) => {
return {
...prev
img: img,
name: name,
weight: weight,
types: types,
abilities: abilities,
moveList: moveList,
height: height
};
});
您的代码有问题,这是使用axios进行Wait的正确方法,
您需要像这样导入axios
从“axios”导入axios;
应使用承诺调用wait
,然后它从api返回如下数据:
const result=wait axios.get(urlPokemonAPI);
这是与代码具有相同逻辑的代码段
useffect(()=>{
const fetchData=async()=>{
//从“axios”导入axios;
试一试{
const result=等待axios.get(urlPokemonAPI);
const pokemon=result.data;
口袋妖怪({
img:pokemon.sprites.front\u默认值,
名称:pokemon.name,
重量:数学圆(口袋妖怪重量/10),
类型:pokemon.types.map(i=>i.type.name),
能力:口袋妖怪.abilities.map(i=>i.ability.name),
moveList:pokemon.moves.map(i=>i.move.name),
高度:口袋妖怪。高度/10
});
const result2=等待axios.get(urlPokemonSpecies);
const data=result2.data;
让描述=”;
data.flavor\u text\u entries.forEach(i=>{
const lang=i.language.name
如果(lang==“en”){
description=i.flavor\u文本;
}
});
让属=”;
data.generals.forEach(i=>{
const lang=i.language.name;
如果(lang==“en”){
属=一属;
}
});
设置口袋妖怪(口袋妖怪=>{
返回{
精灵宝可梦
描述
属
chancetocch:Math.round((data.capture_rate*100)/255),
进化URL,
eggGroups:data.egg\u groups.map(g=>g.name)
};
});
}捕获(e){
控制台日志(e);
}
};
fetchData();
},[urlPokemonAPI,urlPokemonSpecies]);
您是否看到另一个问题:您两次调用setPokemon,让我们再次重写它:
useffect(()=>{
const fetchData=async()=>{
//从“axios”导入axios;
试一试{
const result=等待axios.get(urlPokemonAPI);
const data1=result.data;
const result2=等待axios.get(urlPokemonSpecies);
const data2=result2.data;
函数描述(数据){
让描述=”;
data.flavor\u text\u entries.forEach(i=>{
const lang=i.language.name
如果(lang==“en”){
description=i.flavor\u文本;
}
});
返回说明;
}
函数(数据){
让属=”;
data.generals.forEach(i=>{
const lang=i.language.name;
如果(lang==“en”){
属=一属;
}
});
归属;
}
口袋妖怪({
img:data1.sprites.front\u默认值,
名称:data1.name,
重量:数学四舍五入(数据1.weight/10),
类型:data1.types.map(i=>i.type.name),
能力:data1.abilities.map(i=>i.ability.name),
moveList:data1.moves.map(i=>i.move.name),
高度:数据1.1/10,
描述:resolveDescription(数据2),
属:属(数据2),
chancetocch:Math.round((数据2.capture_rate*100)/255),
进化url:data2.evolution\u chain.url,
eggGroups:data2.egg\u groups.map(g=>g.name)
});
}捕获(e){
控制台日志(e);
}
};
fetchData();
},[urlPokemonAPI,urlPokemonSpecies]);
函数some()用于测试数组是否至少有一个元素通过了条件。我不理解代码,您是想使用.forEach()循环吗?谢谢您的评论。我在forEach上重播了我可以