Есть компонент на react.js. Есть URL: https://swapi.co/api/people - здесь лежит объект всех героев звездных войн. Не могу понять, почему могу вывести, например, их количество count {data.count}
в renderPeople()
и все ок - отображается на локалхосте. Но когда пишу, например, имя {data.results[0].name}
(там, где className='people__item'
) - пишет property '0' of undefined. Но если я создаю глобальную переменную в componentDidMount()
- window.name = data.results[0].name
и потом использую ее в renderPeople()
- то она выводится. Пишу console.log(this.state.data.results[0].name)
в componentDidMount()
- и тоже выводится, но в renderPeople()
- нет. Сначала мне казалось, что я неправильно обращение к объекту делаю, но раз я могу вывести что нужно в componentDidMount
, а в renderPeople()
- нет, то дело не в обращении. Сейчас думаю - может, объект не успевает подгружаться? Как я понимаю, в жизненном цикле компонента сначала начинает выполняться render.
Помогите разобраться, в какую сторону копать - в обращение к объекту или что-то другое.
Вот код:
import React from 'react'
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
data: [],
isLoading: false,
}
}
componentDidMount() {
const xhr = new XMLHttpRequest();
const URL = 'https://swapi.co/api/people';
xhr.open('GET', URL, true);
xhr.send();
this.setState({ isLoading: true })
xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) {
return false
}
if (xhr.status !== 200) {
console.log(xhr.status + ': ' + xhr.statusText)
} else {
this.setState({
data: JSON.parse(xhr.responseText),
isLoading: false,
})
}
//window.arr = [];
window.name = this.state.data.results[0].name;
console.log(this.state.data.results[0].name);
/*for (var i = 0; i < 10; i++) {
window.arr[i] = this.state.data.results[i].name;
}*/
//console.log(window.arr);
//console.log(window.arr[0]);
}
}
renderPeople() {
const { data, isLoading } = this.state
if (isLoading) {
return <img src='/i/preloader.gif' alt='загружаю...' />
} else {
return (
<div className='people'>
<h1 className = 'people__text'>Персонажи</h1>
<p className = 'people__text'>Количество: {data.count}</p>
<ul className = 'people__list'>
<li className = 'people__item'>{}</li>
</ul>
</div>)
}
}
render() {
return (
<div className='App'>
<div className='people-list'>
{this.renderPeople()}
</div>
</div>
)
}
}
export default App
Проблема заключается в том, что в первый раз renderPeople
вызывается до того, как завершится вызов ajax запроса.
Ошибок при обращении к data.count
нет, так как объект data
существует, и в случае обращения до завершения запроса count
просто имеет значение undefined
и никак не выводится.
После завершения запроса render
вызывается еще раз и показывается правильное значение, так как это может происходить довольно быстро, может казаться что ответ показывается сразу.
В случае же с запросом к data.results[0]
, то results
еще не заполнено, так как запрос еще не завершился и идет попытка обращения именно к этому незаполненному полю.
Проблемы можно избежать, если проверять заполнена ли data уже или нет.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
не получаться разобраться с библиотекой monetjs подскажите пожалуйстаНужно посчитать сколько времени прошло с определенного момента, то есть...
Здравтсвуйте, возникла проблема, при использовании Axios вместе с Vuejs
Есть приложение на node js которое копирует директорию и загружает её на сервер таким образом: