问题
Unlike ListView we can update this.state.datasource. Is there any method or example to update FlatList or re-render it?
My goal is to update the text value when user press button ...
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} />
回答1:
Use the extraData
property on your FlatList component.
As the documentation states:
By passing
extraData={this.state}
toFlatList
we make sureFlatList
will re-render itself when thestate.selected
changes. Without setting this prop,FlatList
would not know it needs to re-render any items because it is also aPureComponent
and the prop comparison will not show any changes.
回答2:
For quick and simple solution Try:
set extra data to a boolean value.
extraData={this.state.refresh}
Toggle the value of boolean state when you want to re-render/refresh list
this.setState({ refresh: !this.state.refresh })
回答3:
Oh that's easy, just use extraData
You see the way extra data works behind the scenes is the FlatList or the VirtualisedList just checks wether that object has changed via a normal onComponentWillReceiveProps
method.
So all you have to do is make sure you give something that changes to the extraData
.
Here's what I do:
I'm using immutable.js so all I do is I pass a Map (immutable object) that contains whatever I want to watch.
<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}
/>
))}
/>
In that way, when this.props.foo
or this.props.bar
change, our CustomComponentRow
will update, because the immutable object will be a different one than the previous.
回答4:
OK.I just found out that if we want the FlatList to know the data change outside of the data prop,we need set it to extraData, so I do it like this now:
<FlatList data={...} extraData={this.state} .../>
refer to : https://facebook.github.io/react-native/docs/flatlist#extradata
回答5:
If you are going to have a Button, you can update the data with a setState inside the onPress. SetState will then re-render your FlatList.
回答6:
after lots of searching and looking for real answer finally i got the answer which i think it is the best :
<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 }**
/>
.....
my main problem was (KeyExtractor) i was not using it like this . not working : keyExtractor={ (item) => item.ID} after i changed to this it worked like charm i hope this helps someone.
回答7:
I solved this problem by adding extraData={this.state}
Please check code below for more detail
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.arr}
extraData={this.state}
renderItem={({ item }) => <Text style={styles.item}>{item}</Text>}
/>
</View>
);
}
回答8:
In react-native-flatlist, they are a property called as extraData. add the below line to your flatlist.
<FlatList
data={data }
style={FlatListstyles}
extraData={this.state}
renderItem={this._renderItem}
/>
回答9:
I have replaced FlatList
with SectionList
and it is updates properly on state change.
<SectionList
keyExtractor={(item) => item.entry.entryId}
sections={section}
renderItem={this.renderEntries.bind(this)}
renderSectionHeader={() => null}
/>
The only thing need to keep in mind is that section
have diff structure:
const section = [{
id: 0,
data: this.state.data,
}]
回答10:
For me, the trick was extraData and drilling down into the item component one more time
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 });
}
}
}
回答11:
Put variables that will be changed by your interaction at extraData
You can be creative.
For example if you are dealing with a changing list with checkboxes on them.
<FlatList
data={this.state.data.items}
extraData={this.state.data.items.length * (this.state.data.done.length + 1) }
renderItem={({item}) => <View>
回答12:
If we want the FlatList to know the data change both prop and state,we can construct an object referencing both prop and state and refresh the flatlist.
const hasPropOrStateChange = { propKeyToWatch: this.props, ...this.state};
<FlatList data={...} extraData={this.hasPropOrStateChange} .../>
Docs: https://facebook.github.io/react-native/docs/flatlist#extradata
回答13:
Just use:
onRefresh={true}
inside your flatList
component.
回答14:
In this example, to force a re-render, just change the variable machine
const [selected, setSelected] = useState(machine)
useEffect(() => {
setSelected(machine)
}, [machine])
回答15:
Flatlist's extraData wasn't working for me and I happened to be using a prop from redux. This sounded similar to issues from the comments in ED209's answer. I ended up manually calling setState when I receive the 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}
/>
For those of you using > React 17 use getDerivedStateFromProps
来源:https://stackoverflow.com/questions/43397803/how-to-re-render-flatlist