可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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}
to FlatList
we make sure FlatList
itself will re-render when the state.selected
changes. Without setting this prop, FlatLis
t would not know it needs to re-render any items because it is also a PureComponent
and the prop comparison will not show any changes.
回答2:
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.
回答3:
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
})
回答4:
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.
回答5:
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
回答6:
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,
}]
回答7:
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 });
}
}
}
回答8:
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>
回答9:
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>
);
}
回答10:
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