Приложение "Звёздные войны". Ч2.
Когда определились с источником данных, выясним, какие компоненты нам понадобятся
Приложение будет выглядеть приблизительно так
Соответственно, нам нужен будет хедер с логотипом и вкладками люди-планеты-корабли, блок "случайная планета" и три похожих блока с описанием людей, планет и кораблей
Получение данных с сервера
Рассмотрим компонент random-planet, который должен получать от сервера данные о планете и раз в несколько секунд обновлять ихИмпортируем файл swapi-service.js
import SwapiService from '../../services/swapi-service';
Внутри класса RandomPlanet инициализируем swapiService
swapiService = new SwapiService();
Создаём стейт
state = {
id: null,
name: null,
population: null,
rotationPeriod: null,
diameter: null
};
Создаём метод updatePlanet(), который будет возвращать данные о планете по её id
updatePlanet() {
const id = 5;
this.swapiService
.getPlanet(id)
.then(this.onPlanetLoaded);
}
Внутри него вызываем метод onPlanetLoaded, который обновляет стейт
onPlanetLoaded = (planet) => {
this.setState({
id: planet.id,
name: planet.name,
population: planet.population,
rotationPeriod: planet.rotation_period,
diameter: planet.diameter
});
};
Для вызова updatePlanet() используем конструктор
constructor() {
super();
this.updatePlanet();
}
Сайт https://swapi.co/ не содержит никаких картинок. Зато картинки есть на сайте https://starwars-visualguide.com/
Больше того, последний использует API первого и все картинки имеют те же id, что и swapi.co
Например,
https://starwars-visualguide.com/assets/img/planets/12.jpg
Получить число из строки позволяет регулярное выражение, например, такое
planet.url.match(/\d+/g)
Займёмся рефакторингом кода
Создаём функцию преобразующую ответ API в нужный нам объект в swapi-service.js
_transformPlanet(planet) {
return {
id: planet.url.match(/\d+/g),
name: planet.name,
population: planet.population,
rotationPeriod: planet.rotation_period,
diameter: planet.diameter
}
Изменим код getPlanet
async getPlanet(id) {
const planet = await this.getResource(`/planets/${id}/`);
return this._transformPlanet(planet);
}
В компоненте random-planet благодаря этому существенно сокращается количество кода, он становится чище проще и понятнее
state = {
planet: {}
};
onPlanetLoaded = (planet) => {
this.setState({ planet });
};
updatePlanet() {
const id = Math.floor(Math.random() * 18 + 2);
this.swapiService
.getPlanet(id)
.then(this.onPlanetLoaded);
}
И немного изменяем деструктуризацию
const { planet: {id, name, population,
rotationPeriod, diameter} } = this.state;
Всё работает.
Выводы
1. Изолируйте код, который обрабатывает данные2. Отделяйте модель данных API от модели данных приложения