Перейти к основному содержимому

Практика - Stargate

В этом уроке мы закрепим полученную теорию и создадим мобильное приложение которое получает фильмы с сервера и отображает их на экране.

star gate

Первое, что мы сделаем это сверстаем хедер. Компонент состоит из компонента View и Text. Вставьте этот код в файл index.js.

примечание

Обратите внимание, что название файла куда нужно писать код я пишу сверху в LiveEditor.

State - useState

Теперь получим данные в хедер из состояния компонента state используя для этого хук useState

Архитектура приложения

Если мы все будем писать в одном файле index.js, то в скором времени нам сложно будет поддерживать приложение, так как количество кода на одной странице достигнет критического предела, что сломает ваш мозг.

Поэтому важно с самого начала создать удобную организационную структуру компонентов.

В общем я организую свои проекты так:

  • src/components - это строительные блоки из которых строится приложение - UIKit.
  • src/screens - это экраны на которых собирается приложение.
  • src/logic - это слой бизнес логики и store.

components

Исходя из архитектуры нашего проекта создаем папку src, в ней папку components, далее Header c файлом index.js. Где вспоминаем тему по props и передаем в хедер title

src/components/Header/index.js
import React from 'react'
import { StyleSheet, View, Text } from 'react-native'

const styles = StyleSheet.create({
viewStyle: {
backgroundColor: '#30d0fe',
justifyContent: 'center',
paddingLeft: 22,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.2,
elevation: 2,
height: 90
},
textStyle: {
color: '#fff',
fontSize: 28
}
})

const Header = ({ title }) => {
const { textStyle, viewStyle } = styles
return (
<View style={viewStyle}>
<Text style={textStyle}>{title}</Text>
</View>
)
}

export { Header }

Точка входа

Чтобы не плодить лапшу из импортов:

import Header from './src/components/Header'
import Card from './src/components/Card'
import Storage from './src/components/Storage'

Намного изящней импортировать их в одной строке, например так:

import { Header, Card, Storage } from './src/components'

Для этого мы создаем в папке ./src/components файл куда будет добавлять по аналогии с компонентом Header другие компоненты:

src/components/index.js
export * from './Header'

Импортируем код из UI Kit

Теперь можно импортировать компонент Header и проверить как все работает:

src/index.js
import React from 'react'
import { Header } from './src/components' // здесь импортируем

const App = () => (
<>
<Header title="STAR GATE" />
</>
)

export default App

Правим рутовый index.js

index.js
import {AppRegistry} from 'react-native';
import App from './src'; // здесь
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App)

useEffect

Что если нам нужно отобразить данные с сервера? Для этого мы используем хук useEffect в связке с useState, где мы:

  1. Получаем данные с сервера через fetch в хуке useEffect
  2. Передаем данные в хук useState
src/index.js
import React, { useState, useEffect } from 'react'
import { View } from 'react-native'
import { Header } from './components'

const App = () => {
const [data, setData] = useState('')

useEffect(async () => {
try {
const response = await fetch('https://leelachakra.com/resource/stargate/data.json')
const json = await response.json()
setData(json)
} catch (e) {
console.log(e)
}
}, [])

console.log(`data`, data)

return (
<View>
<Header title="STAR GATE" />
</View>
)
}

export default App

Открываем Debbuger, где видим полученные данные.

data

ImageCard

Мы получили данные и теперь мы сверстаем компонет карточку ImageCard под отображение фильма.

src/components/ImageCard/index.js
import React from 'react'
import { Image, View, Text, StyleSheet, Dimensions } from 'react-native'

const w = Dimensions.get('window').width

const styles = StyleSheet.create({
container: {
width: w / 2.4,
top: 20
},
sub: {
shadowColor: '#000',
borderRadius: 10,
backgroundColor: 'white',
shadowRadius: 8,
shadowOffset: { width: 0, height: 5 },
shadowOpacity: 0.4
},
h1: {
paddingVertical: 10,
fontSize: 18,
alignSelf: 'center',
textAlign: 'center'
},
cover: {
width: w / 2.4,
height: w * 0.63,
borderRadius: 10
}
})

const ImageCard = ({ data }) => {
const { container, sub, h1, cover } = styles
const { image, name } = data
return (
<View style={container}>
<View style={sub}>
<Image style={cover} source={{ uri: image }} />
</View>
<Text style={h1}>{name.toUpperCase()}</Text>
</View>
)
}

export { ImageCard }

imageCard

Flatlist

Вспоминаем из прошлых уроков компонент FlatList благодаря которому мы создаем список наших фильмов.

src/index.js
import React, { useState, useEffect } from 'react'
import { View, FlatList, StyleSheet, Text } from 'react-native'
import { Header, ImageCard } from './components'

const App = () => {
const [data, setData] = useState([])

useEffect(async () => {
try {
const response = await fetch('https://leelachakra.com/resource/stargate/data.json')
const json = await response.json()
console.log(`json`, json)
setData(json)
} catch (e) {
console.log(e)
}
}, [])

return (
<FlatList
ListHeaderComponent={<Header title="STAR GATE" />}
columnWrapperStyle={{ justifyContent: 'space-around' }}
numColumns={2}
data={data}
renderItem={({ item }) => <ImageCard data={item} />}
keyExtractor={item => item.id.toString()}
/>
)
}

export default App

Из нового в нем мы видим свойства:

ListHeaderComponent

Для отображения хэдера в списке используется свойство ListHeaderComponent, в которое мы передаем компонент Header.

numColumns

Количество колонок.

columnWrapperStyle

Это свойство стилизации обертки списка.

keyExtractor

Используется для извлечения уникального ключа для данного элемента по указанному индексу. Ключ используется для кеширования и в качестве клавиши реагирования для отслеживания переупорядочения элементов. Эти уникальные ключи позволяют VirtualizedList (на которых построен FlatList) отслеживать элементы и действительно важны с точки зрения эффективности.

imageCard

EnglishMoji!

Проблемы?

Problem

Пишите в Discord или телеграмм чат, а также подписывайтесь на наши новости

JavaScript Camp

Done

Чтобы узнать, насколько хорошо вы усвоили этот урок, пройдите тест в мобильном приложении нашей школы по этой теме или в боте Telegram.

EnglishMoji!