• Home
  • React Native
  • Renderowanie listy elementów za pomocą ScrollView i FlatListy

Renderowanie listy elementów za pomocą ScrollView i FlatListy

Ok, chcemy wyświetlić listę elementów w React Native. Możemy to zrobić na kilka sposobów, tutaj przedstawione zostaną dwa – ScrollView i FlatList.

ScrollView to komponent, który powinien posiadać ograniczoną wysokość (ustawioną np. poprzez ustawienie parametru {flex: 1} ). Renderuje on wszystkie swoje dzieci na raz, co przy ich dużej ilości sprawia, że aplikacja wolniej się ładuje. Może to rodzić problemy z wydajnością, ponieważ aplikacja musi zaczekać na wyrenderowanie wszystkich komponentów – dzieci zanim wyświetli je na ekranie. Komponent ScrollView jest więc odpowiedni dla mniejszych list.

Większe listy lepiej jest renderować za pomocą komponentu FlatList, który ładuje tylko część komponentów – dzieci (tzw. leniwe ładowanie), przede wszystkich tych, które aktualnie widoczne są na ekranie. Podczas scrollowania FlatLista ładuje nowe komponenty i usuwa te, które nie są już widoczne. Poza tym oferuje jeszcze szereg innych funkcjonalności, których nie oferuje ScrollView, ich listę znajdziesz tu: Flatlist

Stwórzmy teraz nowy folder o nazwie: components, a w nim dwa komponenty: pierwszy zawierać będzie naszą listę: List.js, a drugi dane, które lista powinna wyświetlać: Data.js.

Komponent App.js powinien zwracać nasz główny komponent z listą, kod będzie zatem bardzo prosty:

App.js:

 import React, {Component} from 'react';
import List from './components/List';

export default class App extends Component {
render() {
return <List />
}};

Natomiast nasze dane wyglądać będą tak:

Data.js:

 
export default Data = [
{id: 1, text: 'Item One', color: 'red'},
{id: 2, text: 'Item Two', color: 'blue'},
{id: 3, text: 'Item Three', color: 'yellow'},
{id: 4, text: 'Item Four', color: 'green'},
{id: 5, text: 'Item Five', color: 'orange'},
{id: 6, text: 'Item Six', color: 'red'},
{id: 7, text: 'Item Seven', color: 'blue'},
{id: 8, text: 'Item Eight', color: 'yellow'},
{id: 9, text: 'Item Nine', color: 'green'},
{id: 10, text: 'Item Ten', color: 'orange'},
{id: 11, text: 'Item Eleven', color: 'red'},
{id: 12, text: 'Item Twelve', color: 'blue'},
{id: 13, text: 'Item Thirteen', color: 'yellow'},
{id: 14, text: 'Item Fourteen', color: 'green'},
{id: 15, text: 'Item Fifteen', color: 'orange'},
]


React Native ScrollView

React native ScrollList scrolling

Zaczniemy od komponentu List.js. Aby wyświetlić dane w postaci listy za pomocą ScrollView musimy importować kilka komponentów z react-native. i wyrenderować je na ekranie:

List.js:


import React, {Component} from 'react';
import {StyleSheet, Text, View, ScrollView } from 'react-native';
import Data from './Data';

export default class List extends Component {
render() {
return (
<View style={styles.contentContainer}>
<View style={styles.header}>
<Text style={styles.headerText}> List Header </Text>
</View>
<ScrollView >
<View>
{item}
</View>
</ScrollView>
</View>
)
}
};

Powyżej zwracamy nagłówek, zawierający tekst, a pod nim komponent ScrollView, zawierający komponenty-dzieci, które możemy scrollować. Komonenty-dzieci zwracać będziemy z komponentu Data.js

const item = Data.map( (item, index) => {
return <View key={item.id} style={styles.item}>
<View style={styles.marginLeft}>
<View style={[styles.menu, { backgroundColor: item.color }]}></View>
<View style={[styles.menu, { backgroundColor: item.color }]}></View>
<View style={[styles.menu, { backgroundColor: item.color }]}></View>
</View>
<Text style={styles.text}>{item.text} </Text>
</View>
})

Na koniec dołożymy style:

 
const styles = StyleSheet.create({
header: {
height: 60,
backgroundColor: 'orange',
alignItems: 'center',
justifyContent: 'center',
},
headerText: {
fontSize: 20,
fontWeight: 'bold',
color: 'white',
},
contentContainer: {
backgroundColor: 'white',
},
item: {
flexDirection: 'row',
borderBottomWidth: 1,
borderBottomColor: 'grey',
alignItems: 'center',
},
marginLeft: {
marginLeft: 5,
},
menu: {
width: 20,
height: 2,
backgroundColor: '#111',
margin: 2,
borderRadius: 3,
},
text: {
marginVertical: 30,
fontSize: 20,
fontWeight: 'bold',
marginLeft: 10
, }
})

Całość będzie wyglądać tak:

List.js:

 
import React, {Component} from 'react';
import {StyleSheet, Text, View, ScrollView } from 'react-native';
import Data from './Data';

export default class List extends Component {
render() {
const item = Data.map( (item, index) => {
return <View key={item.id} style={styles.item}>
<View style={styles.marginLeft}>
<View style={[styles.menu, { backgroundColor: item.color }]}></View>
<View style={[styles.menu, { backgroundColor: item.color }]}></View>
<View style={[styles.menu, { backgroundColor: item.color }]}></View>
</View>
<Text style={styles.text}>{item.text} </Text>
</View>
})
return (
<View style={styles.contentContainer}>
<View style={styles.header}>
<Text style={styles.headerText}> List Header </Text>
</View>
<ScrollView >
<View>
{item}
</View>
</ScrollView>
</View>
)
}
};

const styles = StyleSheet.create({
header: {
height: 60,
backgroundColor: 'orange',
alignItems: 'center',
justifyContent: 'center',
},
headerText: {
fontSize: 20,
fontWeight: 'bold',
color: 'white',
},
contentContainer: {
backgroundColor: 'white',
},
item: {
flexDirection: 'row',
borderBottomWidth: 1,
borderBottomColor: 'grey',
alignItems: 'center',
},
marginLeft: {
marginLeft: 5,
},
menu: {
width: 20,
height: 2,
backgroundColor: '#111',
margin: 2,
borderRadius: 3,
},
text: {
marginVertical: 30,
fontSize: 20,
fontWeight: 'bold',
marginLeft: 10
, }
})




React Native FlatList Example

Czas na kolejną listę. Tym razem zamiast ScrollView użyjemy komponentu Flatlist. W tym wypadku nie ma potrzeby samodzielnego mapowania danych, flatlista zrobi to za nas. Dane odczytane zostaną z właściwości data. Podobnie jak w przypadku ScrollView, we flatliście każde dziecko powinno być oznaczone innym kluczem. Możemy w tym celu użyć właściwości keyExtractor, która przyporządkuje odpowiedni klucz do dziecka. Klucz ten powinien być podany w stringu. Funkcja renderItem wyrenderuje komponenty-dzieci według podanego przez nas schematu. Komponent List.js będzie zatem wyglądał tak:

List.js

 

import React, {Component} from 'react';
import {StyleSheet, Text, View, FlatList } from 'react-native';
import Data from './Data';

export default class List extends Component {

renderItem = ({item}) => (
<View style={styles.item}>
<View style={styles.marginLeft}>
<View style={[styles.menu, { backgroundColor: item.color }]}></View>
<View style={[styles.menu, { backgroundColor: item.color }]}></View>
<View style={[styles.menu, { backgroundColor: item.color }]}></View>
</View>
<Text style={styles.text}> {item.text} </Text>
</View>
)

render() {
return (
<View style={styles.contentContainer}>
<View style={styles.header}>
<Text style={styles.headerText}> List Header </Text>
</View>
<FlatList
data={Data}
keyExtractor={(item) => item.id.toString()}
renderItem={this.renderItem}
/>
</View>
)
}
};

const styles = StyleSheet.create({
header: {
height: 60,
backgroundColor: 'orange',
alignItems: 'center',
justifyContent: 'center',
},
headerText: {
fontSize: 20,
fontWeight: 'bold',
color: 'white',
},
contentContainer: {
backgroundColor: 'white',
},
item: {
flexDirection: 'row',
borderBottomWidth: 1,
borderBottomColor: 'grey',
alignItems: 'center',
},
marginLeft: {
marginLeft: 5,
},
menu: {
width: 20,
height: 2,
backgroundColor: '#111',
margin: 2,
borderRadius: 3,
},
text: {
marginVertical: 30,
fontSize: 20,
fontWeight: 'bold',
marginLeft: 10
, }
})

Efekt uzyskujemy podobny, jak we wcześniejszym przypadku, ale funkcjonalność jest trochę inna (o czym wspomniałam na wstępie), dla przypomnienia – flatlista nie renderuje wszystkich komponentów-dzieci na raz, a ScrollView tak.

Joanna

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *