Я пытаюсь создать свое первое гибридное приложение с ReactNative. У меня проблема с моим Array.map…
class HomeScreen extends React.Component {
state = {
isLoading: false,
captured: false,
wished: false,
exchanged: false,
data: {}
};
async getPokemonFromApiAsync() {
try {
this.setState({isLoading: true});
let response = await fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20');
return this.setState({
isLoading: false,
data: await response.json()
});
} catch (error) {
console.error(error);
}
(...)
componentWillMount() {
this.getPokemonFromApiAsync()
}
(...)
result = (result = this.state.data.results) => {
console.info('test', this.state.data);
return (
<View>
(...)
result.map( (item, index) => {
(...)
}
</View>
)
}
}
Я не понимаю, почему моя функция getPokemonFromApiAsync пуста. Симулятор iOS возвращает TypeError: Undefined не является объектом (оценка 'result.map')
И при добавлении конструктора вроде:
constructor(props) {
super(props)
this.getPokemonFromApiAsync = This.getPokemonFromApiAsync.bind(this)
}
У меня много ошибок в консоли:
Предупреждение: невозможно вызвать %s для еще не смонтированного компонента. Это недопустимо, но может указывать на ошибку в вашем приложении. Вместо этого назначьте this.state напрямую или определите свойство класса state = {}; с желаемым состоянием в компоненте %s., setState, HomeScreen
Для меня это нормально…
Каков хороший жизненный цикл для асинхронного HTTP-запроса?
Спасибо. Но у меня такая же ошибка. console.info('test', this.state.data) возвращает объект {}. Моя проблема заключается в том, что данные извлекаются, но не извлекаются в состоянии.
Что ж, вам не хватает объекта конфигурации в вашем операторе выборки. убедитесь, что вы предоставили их. Я подозреваю, что ваша выборка не удалась.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Лучший способ использовать библиотеку axios github связь
npm install axios
Наконец, еженедельные загрузки составляют более 4 000 000+ Github Starts 50 000+
Лучший способ - реализовать ваши значения состояния, когда ваше обещание разрешено с использованием "тогда".
let response = fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20')
.then((response) => {
this.setState({
isLoading: false,
data: response.json()
});
});
Возможно, вы можете обработать свои данные (result.map) в обратном вызове Promise и напрямую вставить результат в свой компонент.
И, кстати, вызовы XHR обычно обрабатываются в методе componentDidMount.
Ваша ошибка вызвана тем, как вы настроили свой начальный 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>
);
}
}
Привет гость из будущего, для получения дополнительной информации: facebook.github.io/react-native/docs/network#using-fetch
Причина, по которой вы получаете сообщение об ошибке TypeError: Undefined is not an object (evaluating 'result.map'), заключается в том, что вы получаете result от this.state.data.results, но поскольку данные асинхронны, при первом отображении данные {} (потому что вы устанавливаете их в состоянии), поэтому data.result это undefined, и вы нельзя использовать .map() в неопределенном.
Чтобы решить эту проблему, вы можете проверить, не является ли data.result неопределенным, прежде чем визуализировать его.
return (
<View>
(...)
result && result.map( (item, index) => {
(...)
}
</View>
)
Скиньте Ждите в состояние и будет вам счастье.