Практика - Stargate
В этом уроке мы закрепим полученную теорию и создадим мобильное приложение которое получает фильмы с сервера и отображает их на экране.
Первое, что мы сделаем это сверстаем хедер. Компонент состоит из компонента 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
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
другие компоненты:
export * from './Header'
Импортируем код из UI Kit
Теперь можно импортировать компонент Header
и проверить как все работает:
import React from 'react'
import { Header } from './src/components' // здесь импортируем
const App = () => (
<>
<Header title="STAR GATE" />
</>
)
export default App
Правим рутовый 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
, где мы:
- Получаем данные с сервера через
fetch
в хукеuseEffect
- Передаем данные в хук
useState
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, где видим полученные данные.
ImageCard
Мы получили данные и теперь мы сверстаем компонет карточку ImageCard
под отображение фильма.
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 }
Flatlist
Вспоминаем из прошлых уроков компонент FlatList благодаря которому мы создаем список наших фильмов.
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) отслеживать элементы и действительно важны с точки зрения эффективности.
Проблемы?
Пишите в Telegram или ВКонтакте, а также подписывайтесь на наши новости
Done
Чтобы узнать, насколько хорошо вы усвоили этот урок, пройдите тест в мобильном приложении нашей школы по этой теме или в боте Telegram.