在 React 中使用 API 时无法读取未定义错误的属性
Cannot read properties of undefined error when working with an API in React
我正在从 API 中获取数据,其中 returns 对象数组采用这种格式。
{Name: 'hitmonchan', Description: 'Fighting-type Pokémon introduced in Generation I'}
{Name: 'Gogoat', Description: 'A quadrupedal, hooved Pokémon similar to a goat'}... and so on
这是我正在尝试做的事情。我取出所有超过 500 只的小精灵,将它们塞入一个名为 allPokemons
的数组中。然后我想用列表中的 4 个随机口袋妖怪做一些事情。所以我将有一个名为 smallRandomPokemonArray
的数组,其中只有从 allPokemon
数组中随机选择的四个口袋妖怪。
import { useEffect, useState } from 'react';
import { getallPokemons } from '../services/pokemonapi';
const empty_pokemon = {
'Name': '',
'Description': ''
}
function PokemonComponent() {
const [allPokemons, setAllPokemons] = useState([]);
const [smallRandomPokemonArray, setSmallRandomPokemonArray] = useState([]);
useEffect(() => {
getAll();
}, []);
const getAll = () => {
getallPokemons()
.then(data => {
//actual data with over 500 objects show in log
console.log(data);
setAllPokemons(data);
randomChooser(data.length)
})
}
const randomChooser = (length) => {
let temporaryArray = [];
for (let i = 0; i < 4; i++) {
const randomIndex = Math.floor(Math.random() * length);
//First Problem: this is returning index in numbers followed by undefined... why?
console.log(randomIndex + " " + allPokemons[randomIndex]);
temporaryArray.push(allPokemons[randomIndex]);
//Second Problem: this is also returning "temp undefined"
console.log("temp " + temporaryArray[i]);
}
setSmallRandomPokemonArray(temporaryArray);
}
return (
<>
<div className="pokemondiv">
{
smallRandomPokemonArray.map((element) => (
<div>
<p>{element.Name}</p>
<p>{element.Description}</p>
</div>
))
}
</div>
</>
)
}
export default PokemonComponent;
当我尝试从 setSmallRandomPokemonArray
中打印值时,我得到了错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'Name')
此外,请查看代码中的 First problem and Second problem
部分。它们在 console.log 中也显示为未定义。根据我的理解,它应该可以工作,因为当我开始随机化它时 allPokemons
已经存在。然后我将四个随机值推送到 smallRandomPokemonArray
。我不知道为什么会抛出错误。
问题
您正在 getAll
的 setAllPokemons(data);
之后呼叫 randomChooser(data.length)
。此时randomChooser
里面使用的allPokemons
还是[]
.
emptyArray[0] = undefined. undefined.Name = Cannot read properties of undefined. The takeaway is that when you call a setState
, the related state
is updated asynchronously. A re-render is needed to have the updated value.
第 1 个解决方案
将 getAll
更改为下面的代码,因此它唯一的工作就是填充 allPokemons
状态:
const getAll = () => {
getallPokemons().then((data) => {
setAllPokemons(data);
});
};
使用 useEffect
获取您需要的四个口袋妖怪:
useEffect(() => {
/*
I moved randomChooser here, so you don't have to put it in useEffect's
dependencies array, which if you do, you should wrap randomChooser in a
useCalback, as otherwise you get an infinite call.
*/
const randomChooser = (length) => {
const temporaryArray = [];
for (let i = 0; i < 4; i++) {
const randomIndex = Math.floor(Math.random() * length);
temporaryArray.push(allPokemons[randomIndex]);
}
setSmallRandomPokemonArray(temporaryArray);
};
if (allPokemons.length <= 0) return;
randomChooser(allPokemons.length);
}, [allPokemons]);
解决方案 2
更改 randomChooser
以便它接收数组,而不是它的长度:
const randomChooser = (allPokemons) => {
let temporaryArray = [];
for (let i = 0; i < 4; i++) {
const randomIndex = Math.floor(Math.random() * allPokemons.length);
temporaryArray.push(allPokemons[randomIndex]);
}
setSmallRandomPokemonArray(temporaryArray);
};
更改 getAll
以便您将数据提供给 randomChooser
:
const getAll = () => {
getallPokemons().then((data) => {
setAllPokemons(data);
randomChooser(data);
});
};
您在randomChooser
中使用它的地方尚未设置allPokemons
。 react 将在函数完成后设置所有状态 运行。
您需要将数据传递到 randomChooser
.
const randomChooser = (data) => {
const length = data.length
let temporaryArray = [];
for (let i = 0; i < 4; i++) {
const randomIndex = Math.floor(Math.random() * length);
//First Problem: this is returning index in numbers followed by undefined... why?
console.log(randomIndex + " " + data[randomIndex]);
temporaryArray.push(data[randomIndex]);
//Second Problem: this is also returning "temp undefined"
console.log("temp " + temporaryArray[i]);
}
setSmallRandomPokemonArray(temporaryArray);
}
我正在从 API 中获取数据,其中 returns 对象数组采用这种格式。
{Name: 'hitmonchan', Description: 'Fighting-type Pokémon introduced in Generation I'}
{Name: 'Gogoat', Description: 'A quadrupedal, hooved Pokémon similar to a goat'}... and so on
这是我正在尝试做的事情。我取出所有超过 500 只的小精灵,将它们塞入一个名为 allPokemons
的数组中。然后我想用列表中的 4 个随机口袋妖怪做一些事情。所以我将有一个名为 smallRandomPokemonArray
的数组,其中只有从 allPokemon
数组中随机选择的四个口袋妖怪。
import { useEffect, useState } from 'react';
import { getallPokemons } from '../services/pokemonapi';
const empty_pokemon = {
'Name': '',
'Description': ''
}
function PokemonComponent() {
const [allPokemons, setAllPokemons] = useState([]);
const [smallRandomPokemonArray, setSmallRandomPokemonArray] = useState([]);
useEffect(() => {
getAll();
}, []);
const getAll = () => {
getallPokemons()
.then(data => {
//actual data with over 500 objects show in log
console.log(data);
setAllPokemons(data);
randomChooser(data.length)
})
}
const randomChooser = (length) => {
let temporaryArray = [];
for (let i = 0; i < 4; i++) {
const randomIndex = Math.floor(Math.random() * length);
//First Problem: this is returning index in numbers followed by undefined... why?
console.log(randomIndex + " " + allPokemons[randomIndex]);
temporaryArray.push(allPokemons[randomIndex]);
//Second Problem: this is also returning "temp undefined"
console.log("temp " + temporaryArray[i]);
}
setSmallRandomPokemonArray(temporaryArray);
}
return (
<>
<div className="pokemondiv">
{
smallRandomPokemonArray.map((element) => (
<div>
<p>{element.Name}</p>
<p>{element.Description}</p>
</div>
))
}
</div>
</>
)
}
export default PokemonComponent;
当我尝试从 setSmallRandomPokemonArray
中打印值时,我得到了错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'Name')
此外,请查看代码中的 First problem and Second problem
部分。它们在 console.log 中也显示为未定义。根据我的理解,它应该可以工作,因为当我开始随机化它时 allPokemons
已经存在。然后我将四个随机值推送到 smallRandomPokemonArray
。我不知道为什么会抛出错误。
问题
您正在 getAll
的 setAllPokemons(data);
之后呼叫 randomChooser(data.length)
。此时randomChooser
里面使用的allPokemons
还是[]
.
emptyArray[0] = undefined. undefined.Name = Cannot read properties of undefined. The takeaway is that when you call a
setState
, the relatedstate
is updated asynchronously. A re-render is needed to have the updated value.
第 1 个解决方案
将 getAll
更改为下面的代码,因此它唯一的工作就是填充 allPokemons
状态:
const getAll = () => {
getallPokemons().then((data) => {
setAllPokemons(data);
});
};
使用 useEffect
获取您需要的四个口袋妖怪:
useEffect(() => {
/*
I moved randomChooser here, so you don't have to put it in useEffect's
dependencies array, which if you do, you should wrap randomChooser in a
useCalback, as otherwise you get an infinite call.
*/
const randomChooser = (length) => {
const temporaryArray = [];
for (let i = 0; i < 4; i++) {
const randomIndex = Math.floor(Math.random() * length);
temporaryArray.push(allPokemons[randomIndex]);
}
setSmallRandomPokemonArray(temporaryArray);
};
if (allPokemons.length <= 0) return;
randomChooser(allPokemons.length);
}, [allPokemons]);
解决方案 2
更改 randomChooser
以便它接收数组,而不是它的长度:
const randomChooser = (allPokemons) => {
let temporaryArray = [];
for (let i = 0; i < 4; i++) {
const randomIndex = Math.floor(Math.random() * allPokemons.length);
temporaryArray.push(allPokemons[randomIndex]);
}
setSmallRandomPokemonArray(temporaryArray);
};
更改 getAll
以便您将数据提供给 randomChooser
:
const getAll = () => {
getallPokemons().then((data) => {
setAllPokemons(data);
randomChooser(data);
});
};
您在randomChooser
中使用它的地方尚未设置allPokemons
。 react 将在函数完成后设置所有状态 运行。
您需要将数据传递到 randomChooser
.
const randomChooser = (data) => {
const length = data.length
let temporaryArray = [];
for (let i = 0; i < 4; i++) {
const randomIndex = Math.floor(Math.random() * length);
//First Problem: this is returning index in numbers followed by undefined... why?
console.log(randomIndex + " " + data[randomIndex]);
temporaryArray.push(data[randomIndex]);
//Second Problem: this is also returning "temp undefined"
console.log("temp " + temporaryArray[i]);
}
setSmallRandomPokemonArray(temporaryArray);
}