W przeciwieństwie do ListView możemy zaktualizować this.state.datasource. Czy jest jakaś metoda lub przykład aktualizacji FlatList lub ponownego renderowania?
Moim celem jest aktualizacja wartości tekstowej, gdy użytkownik naciśnie przycisk ...
renderEntries({ item, index }) {
return(
<TouchableHighlight onPress={()=> this.setState({value: this.state.data[index].value+1})>
<Text>{this.state.data[index].value}</Text>
</TouchableHighlight>
)
}
<FlatList
ref={(ref) => { this.list = ref; }}
keyExtractor={(item) => item.entry.entryId}
data={this.state.data}
renderItem={this.renderEntries.bind(this)}
horizontal={false} />
reactjs
react-native
react-native-flatlist
shalonteoh
źródło
źródło
PureComponent
co oznacza, że nie wyrenderuje się ponownie, jeśli właściwości pozostają płytkie - równe. Upewnij się, że wszystko, od czegorenderItem
zależy twoja funkcja, jest przekazywane jako właściwość, która nie jest===
po aktualizacji, w przeciwnym razie interfejs użytkownika może się nie zaktualizować po zmianach. Obejmuje to stan właściwościdata
i komponentu nadrzędnego ”. Czy postępujesz zgodnie z tą radą?extraData
ishouldItemUpdate
, nie mogłem uzyskać listy do ponownego renderowania. Skończyło się na tym, że wyczyściłem stan, czekałem, aż się wyrenderuje, a następnie zaktualizowałem stan.this.setState({ data: null }, () => { this.setState({ data: actualData }) });
Odpowiedzi:
Użyj
extraData
właściwości w składniku FlatList.Jak podaje dokumentacja:
źródło
data={this.props.searchBookResults}
i ani nie,extraData={this.state}
aniextraData={this.props}
dla mnie. I teżdata={this.props.searchBookResults}
nie działa. Co robić ?... data={this.props.searchBookResults} extraData={this.state.refresh} onPress={()={this.setState({ refresh: !refresh})}
extraData
, komponent się nie aktualizuje :(extraData
zmieniają się, gdy element [elementy] potomne muszą zostać ponownie wyrenderowane. Na przykład, jeśli elementy listy mogą być aktywne / nieaktywne, upewnij się, że zmienna stanu, czy częśćthis.state
obiektu lubthis.props
obiektu jest tym, co powinna znaleźć się w środkuextraData
. Może to być kursor lub tablica aktywnych przedmiotów itp.shouldComponentUpdate()
, po zaktualizowaniu lub całkowitym skomentowaniu, wszystko działało tak, jak opisano w dokumentacji.Szybkie i proste rozwiązanie Wypróbuj:
ustaw dodatkowe dane na wartość logiczną.
extraData = {this.state.refresh}
Przełącz wartość stanu boolowskiego, gdy chcesz ponownie wyrenderować / odświeżyć listę
this.setState({ refresh: !this.state.refresh })
źródło
this.data.refresh()
. Zamiast tego ustawiamy wartość logiczną i zmieniamy ją. Wartość logiczna sama w sobie nie ma znaczenia, więc jaki jest sens w jej istnieniu? ... (Nie ma sensu, pozathis.state.users
nie działało, mimo że zmieniałem flagę u niektórych użytkowników.Och, to proste, po prostu użyj
extraData
Widzisz, w jaki sposób dodatkowe dane działają za kulisami, to FlatList lub VirtualisedList po prostu sprawdza, czy obiekt zmienił się normalną
onComponentWillReceiveProps
metodą.Więc wszystko, co musisz zrobić, to upewnić się, że podasz coś, co zmieni się w
extraData
.Oto co robię:
Używam immutable.js, więc wszystko, co robię, to przekazanie mapy (niezmiennego obiektu), która zawiera wszystko, co chcę obejrzeć.
<FlatList data={this.state.calendarMonths} extraData={Map({ foo: this.props.foo, bar: this.props.bar })} renderItem={({ item })=>(( <CustomComponentRow item={item} foo={this.props.foo} bar={this.props.bar} /> ))} />
W ten sposób, kiedy
this.props.foo
lubthis.props.bar
zmienimy, naszCustomComponentRow
zaktualizuje się, ponieważ niezmienny obiekt będzie inny niż poprzedni.źródło
extraData
! dzięki za link doVirtualisedList
kodu!OK, właśnie się dowiedziałem, że jeśli chcemy, aby FlatList wiedziała o zmianie danych poza właściwością danych, musimy ustawić ją na extraData, więc robię to teraz tak:
<FlatList data={...} extraData={this.state} .../>
patrz: https://facebook.github.io/react-native/docs/flatlist#extradata
źródło
Jeśli zamierzasz mieć Button, możesz zaktualizować dane za pomocą setState wewnątrz onPress. SetState ponownie wyrenderuje FlatList.
źródło
po wielu poszukiwaniach i szukaniu prawdziwej odpowiedzi w końcu otrzymałem odpowiedź, która moim zdaniem jest najlepsza:
<FlatList data={this.state.data} renderItem={this.renderItem} ListHeaderComponent={this.renderHeader} ListFooterComponent={this.renderFooter} ItemSeparatorComponent={this.renderSeparator} refreshing={this.state.refreshing} onRefresh={this.handleRefresh} onEndReached={this.handleLoadMore} onEndReachedThreshold={1} extraData={this.state.data} removeClippedSubviews={true} **keyExtractor={ (item, index) => index }** /> .....
moim głównym problemem był (KeyExtractor), nie używałem go w ten sposób. nie działa: keyExtractor = {(item) => item.ID} po zmianie na to działało jak urok. Mam nadzieję, że to komuś pomoże.
źródło
this.state.refreshing
i funkcjęhandleRefresh
?Rozwiązałem ten problem, dodając
extraData={this.state}
Proszę sprawdzić kod poniżej, aby uzyskać więcej szczegółówrender() { return ( <View style={styles.container}> <FlatList data={this.state.arr} extraData={this.state} renderItem={({ item }) => <Text style={styles.item}>{item}</Text>} /> </View> ); }
źródło
To tylko rozszerzenie poprzednich odpowiedzi tutaj. Dwie części, aby upewnić się, że dodajesz extraData i że Twój keyExtractor jest unikalny. Jeśli twój keyExtractor jest stały, ponowne wysłanie nie zostanie uruchomione.
<FlatList data={this.state.AllArray} extraData={this.state.refresh} renderItem={({ item,index })=>this.renderPhoto(item,index)} keyExtractor={item => item.id} > </FlatList>
źródło
Wymieniłem
FlatList
zeSectionList
i to jest właściwie aktualizacje na zmiany stanu.<SectionList keyExtractor={(item) => item.entry.entryId} sections={section} renderItem={this.renderEntries.bind(this)} renderSectionHeader={() => null} />
Jedyną rzeczą, o której należy pamiętać, jest to, że
section
mają strukturę diff:const section = [{ id: 0, data: this.state.data, }]
źródło
Dla mnie sztuczka polegała na tym, że extraData i jeszcze raz drążenie w komponencie przedmiotu
state = { uniqueValue: 0 } <FlatList keyExtractor={(item, index) => item + index} data={this.props.photos} renderItem={this.renderItem} ItemSeparatorComponent={this.renderSeparator} /> renderItem = (item) => { if(item.item.selected) { return ( <Button onPress={this.itemPressed.bind(this, item)}>Selected</Button> ); } return ( <Button onPress={this.itemPressed.bind(this, item)}>Not selected</Button>); } itemPressed (item) { this.props.photos.map((img, i) => { if(i === item.index) { if(img['selected') { delete img.selected; } else { img['selected'] = true; } this.setState({ uniqueValue: this.state.uniqueValue +1 }); } } }
źródło
Zmienne, które zostaną zmienione w wyniku interakcji, należy umieścić pod adresem
extraData
Możesz być kreatywny.
Na przykład, jeśli masz do czynienia ze zmieniającą się listą z polami wyboru.
<FlatList data={this.state.data.items} extraData={this.state.data.items.length * (this.state.data.done.length + 1) } renderItem={({item}) => <View>
źródło
Jeśli chcemy, aby FlatList wiedział, że dane zmieniają się zarówno we właściwości , jak i w stanie , możemy skonstruować obiekt odwołujący się do właściwości i stanu i odświeżyć płaską listę.
const hasPropOrStateChange = { propKeyToWatch: this.props, ...this.state}; <FlatList data={...} extraData={this.hasPropOrStateChange} .../>
Dokumenty: https://facebook.github.io/react-native/docs/flatlist#extradata
źródło
W React-native-flatlist są one właściwością o nazwie extraData. dodaj poniższą linię do swojej listy.
<FlatList data={data } style={FlatListstyles} extraData={this.state} renderItem={this._renderItem} />
źródło
W tym przykładzie, aby wymusić ponowne renderowanie, wystarczy zmienić zmienną
machine
const [selected, setSelected] = useState(machine) useEffect(() => { setSelected(machine) }, [machine])
źródło
Po prostu użyj:
onRefresh={true}
wewnątrz twojego
flatList
komponentu.źródło
refreshing
propExtraData Flatlist nie działało dla mnie i zdarzyło mi się używać rekwizytu z Redux. Brzmiało to podobnie do kwestii z komentarzy w odpowiedzi ED209. Skończyło się na ręcznym wywołaniu setState, gdy otrzymałem prop.
componentWillReceiveProps(nextProps: StateProps) { if (this.props.yourProp != null && nextProps.yourProp) { this.setState({ yourState: processProp(nextProps.yourProp) }); } } <FlatList data={this.state.yourState} extraData={this.state.yourState} />
Dla tych z Was, którzy używają> React 17, użyj getDerivedStateFromProps
źródło