Lepsze widoki list w React Native
Ta strona została przetłumaczona przez PageTurner AI (beta). Nie jest oficjalnie zatwierdzona przez projekt. Znalazłeś błąd? Zgłoś problem →
Wielu z Was już eksperymentowało z naszymi nowymi komponentami list po zapowiedzi w grupie społeczności, ale dziś oficjalnie je ogłaszamy! Koniec z ListView czy DataSource, nieaktualnymi wierszami, ignorowanymi błędami i nadmiernym zużyciem pamięci - z najnowszym kandydatem wydania React Native z marca 2017 (0.43-rc.1) możecie wybrać z nowej gamy komponentów najlepiej pasujący do Waszych potrzeb, z doskonałą wydajnością i bogatymi funkcjami od razu po wdrożeniu:
<FlatList>
To podstawowy komponent do tworzenia prostych, wydajnych list. Podaj tablicę danych i funkcję renderItem - to wszystko, czego potrzebujesz:
<FlatList
data={[{title: 'Title Text', key: 'item1'}, ...]}
renderItem={({item}) => <ListItem title={item.title} />}
/>
<SectionList>
Jeśli chcesz wyświetlić dane podzielone na logiczne sekcje, być może z nagłówkami (np. w książce adresowej ułożonej alfabetycznie), a także obsłużyć różnorodne dane i renderowanie (np. widok profilu z przyciskami, edytorem treści, siatką zdjęć, siatką znajomych i listą historii), to właściwy wybór.
<SectionList
renderItem={({item}) => <ListItem title={item.title} />}
renderSectionHeader={({section}) => <H1 title={section.key} />}
sections={[ // homogeneous rendering between sections
{data: [...], key: ...},
{data: [...], key: ...},
{data: [...], key: ...},
]}
/>
<SectionList
sections={[ // heterogeneous rendering between sections
{data: [...], key: ..., renderItem: ...},
{data: [...], key: ..., renderItem: ...},
{data: [...], key: ..., renderItem: ...},
]}
/>
<VirtualizedList>
Implementacja niskopoziomowa z bardziej elastycznym API. Szczególnie przydatna, gdy dane nie są w zwykłej tablicy (np. niemutowalna lista).
Funkcje
Listy są używane w wielu kontekstach, więc wyposażyliśmy nowe komponenty w funkcje pokrywające większość przypadków użycia:
-
Ładowanie przy przewijaniu (
onEndReached). -
Odświeżanie przez przeciągnięcie (
onRefresh/refreshing). -
Konfigurowalne callbacki widoczności (VPV) (
onViewableItemsChanged/viewabilityConfig). -
Tryb poziomy (
horizontal). -
Inteligentne separatory elementów i sekcji.
-
Obsługa wielu kolumn (
numColumns) -
scrollToEnd,scrollToIndexiscrollToItem -
Lepsze typowanie Flow.
Ważne uwagi
-
Stan wewnętrzny poddrzew elementów nie jest zachowywany po opuszczeniu obszaru renderowania. Upewnij się, że wszystkie dane są przechowywane w danych elementów lub zewnętrznych magazynach jak Flux, Redux czy Relay.
-
Te komponenty bazują na
PureComponent, co oznacza że nie będą ponownie renderowane jeślipropspozostaną płytko-równe. Upewnij się, że wszystkie elementy od których zależy funkcjarenderItemsą przekazywane jako prop, który nie jest===po aktualizacji, inaczej interfejs może nie odświeżać zmian. Dotyczy to propadatai stanu komponentu nadrzędnego. Przykład:<FlatList
data={this.state.data}
renderItem={({item}) => (
<MyItem
item={item}
onPress={() =>
this.setState(oldState => ({
selected: {
// New instance breaks `===`
...oldState.selected, // copy old data
[item.key]: !oldState.selected[item.key], // toggle
},
}))
}
selected={
!!this.state.selected[item.key] // renderItem depends on state
}
/>
)}
selected={
// Can be any prop that doesn't collide with existing props
this.state.selected // A change to selected should re-render FlatList
}
/> -
Dla oszczędności pamięci i płynności przewijania, treść renderowana jest asynchronicznie poza ekranem. Może to powodować chwilowe puste miejsca przy szybkim przewijaniu. To kompromis dostosowywany do potrzeb aplikacji, nad którym aktywnie pracujemy.
-
Domyślnie nowe listy szukają propa
keyna każdym elemencie i używają go jako klucza Reacta. Alternatywnie możesz podać własną funkcjękeyExtractor.
Wydajność
Oprócz uproszczenia API, nowe komponenty list oferują znaczną poprawę wydajności. Kluczową zaletą jest niemal stałe zużycie pamięci niezależnie od liczby wierszy. Osiąga się to poprzez "wirtualizację" elementów znajdujących się poza obszarem renderowania - są one całkowicie odmontowywane z hierarchii komponentów, co pozwala odzyskać pamięć JavaScript po komponentach Reacta oraz pamięć natywną z drzewa cieni i widoków UI. Ma to jednak konsekwencję: wewnętrzny stan komponentów nie jest zachowywany, dlatego wszelkie ważne stany muszą być przechowywane poza komponentami, np. w sklepie Relay, Redux lub Flux.
Ograniczenie obszaru renderowania zmniejsza również obciążenie Reacta i platformy natywnej (np. związane z przechodzeniem widoków). Nawet podczas renderowania milionowego elementu, nowe listy nie wymagają iteracji przez wszystkie poprzednie elementy. Możesz nawet przeskoczyć do środka listy za pomocą scrollToIndex bez nadmiernego renderowania.
Wprowadziliśmy też ulepszenia w planowaniu zadań, które poprawiają responsywność aplikacji. Elementy na granicy obszaru renderowania są przetwarzane rzadziej i z niższym priorytetem, po zakończeniu aktywnych gestów, animacji lub innych interakcji.
Zaawansowane zastosowania
W przeciwieństwie do ListView, wszystkie elementy w obszarze renderowania są ponownie renderowane przy każdej zmianie właściwości (props). Zwykle nie stanowi to problemu dzięki ograniczonej liczbie widocznych elementów, ale przy skomplikowanych strukturach warto stosować najlepsze praktyki wydajnościowe Reacta: używaj React.PureComponent i/lub shouldComponentUpdate w swoich komponentach, aby ograniczyć ponowne renderowanie poddrzew.
Jeśli możesz obliczyć wysokość wierszy bez ich renderowania, podaj właściwość getItemLayout dla lepszego doświadczenia użytkownika. Umożliwi to płynniejsze przewijanie do konkretnych pozycji (np. za pomocą scrollToIndex) oraz poprawi wygląd wskaźnika przewijania, ponieważ wysokość zawartości będzie znana bez renderowania.
Do alternatywnych typów danych (np. niemutowalnych list) najlepiej użyć <VirtualizedList>. Akceptuje on właściwość getItem zwracającą dane elementu dla dowolnego indeksu i ma bardziej elastyczne typowanie Flow.
W nietypowych przypadkach możesz dostosować różne parametry: windowSize (kompromis między pamięcią a UX), maxToRenderPerBatch (dostosowanie szybkości wypełniania), onEndReachedThreshold (kontrola ładowania przy przewijaniu) i inne.
Planowane prace
-
Migracja istniejących komponentów (ostateczne wycofanie
ListView) -
Dodawanie nowych funkcji w odpowiedzi na potrzeby (dajcie nam znać!)
-
Obsługa przyklejających się nagłówków sekcji
-
Dodatkowe optymalizacje wydajności
-
Wsparcie dla funkcyjnych komponentów elementów ze stanem