Ваша ошибка вызвана тем, как вы установили исходное значение data
в состоянии.
Вы настроили его как:
state = {
isLoading: false,
captured: false,
wished: false,
exchanged: false,
data: {} // <- here you define it as an object, with no parameters
};
Вы должны установить его как объект с параметром результатов`. Итак, ваше начальное состояние должно выглядеть как
state = {
isLoading: false,
captured: false,
wished: false,
exchanged: false,
data: { results: [] } // <- here you should define the results inside the object
};
Причина, по которой вы получаете ошибку:
TypeError: Undefined is not an object (evaluating 'result.map')
Это потому, что при первоначальном рендеринге, до того как ваш ответ на выборку вернулся, он пытается map
преодолеть this.state.data.results
, которого не существует. Необходимо убедиться, что в состоянии есть начальное значение для results
.
Это должно остановить первоначальную ошибку, однако вам необходимо убедиться, что то, что вы сохраняете в состояние для data
, также является массивом, в противном случае вы продолжите получать ту же ошибку.
componentWillMount
устарел, и вы должны использовать componentDidMount
.
Кроме того, так как вы вызываете асинхронную функцию внутри себя componentWillMount
, вы должны выполнить ее рефакторинг следующим образом:
async componentDidMount() {
await this.getPokemonFromApiAsync()
}
Так что монтирование не происходит до тех пор, пока не будет завершен запрос на выборку.
Я бы также реорганизовал ваш getPokemonFromApiAsync
, чтобы вы получили response.json()
, прежде чем пытаться установить его в состояние. Вам также не нужен оператор return, так как this.setState
ничего не возвращает.
async getPokemonFromApiAsync() {
try {
this.setState({isLoading: true});
let response = await fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20');
let data = await response.json(); // get the data
this.setState({
isLoading: false,
data: data // now set it to state
});
} catch (error) {
console.error(error);
}
Полдник:
Вот очень простая закуска, показывающая работающий код https://snack.expo.io/@andypandy/pokemon-fetch
Код для перекуса:
export default class App extends React.Component {
state = {
isLoading: false,
captured: false,
wished: false,
exchanged: false,
data: { results: [] } // <- here you should define the results inside the object
};
getPokemonFromApiAsync = async () => {
try {
this.setState({ isLoading: true });
let response = await fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20');
let data = await response.json(); // get the data
this.setState({
isLoading: false,
data: data // now set it to state
});
} catch (error) {
console.error(error);
}
}
async componentDidMount () {
await this.getPokemonFromApiAsync();
}
render () {
return (
<View style={styles.container}>
{this.state.data.results.map(item => <Text>{item.name}</Text>)}
</View>
);
}
}