I am having a problem with the new FlatList component. In particular, it does not overwrite lines, even if the props depend on line changes.
FlatList docs say that:
This is a PureComponent, which means that it will not re-render if the props remain shallow. Make sure that all your renderItem function depends on being passed as a support, which is not === after updates, otherwise your user interface may not be updated when changes are made. This includes prop and parent component data.
QUESTION
However, seeing how I change the identifier of the selected category object - an alert that should indicate whether the row is selected or not, I believe that the props should be repeated. Am I mistaken?
I tested componentWillReceiveProps methods for both list components and strings, and the list gets updated just fine, but the string lifecycle method is never called.
If I turn on a random, useless logical state value in the list component and switch it back and forth when updating the attribute, it works - but I don’t know why?
state = { updated: false };
componentWillReceiveProps(nextProps) {
this.setState(oldstate => ({
updated: !oldstate.updated,
}));
}
<FlatList
data={this.props.items.allAnimalCategories.edges}
renderItem={this._renderRow}
horizontal={true}
keyExtractor={(item, index) => item.node.id}
randomUpdateProp={this.state.updated}
/>
THE CODE
The structure of my code is as follows: I have a container component with all the logic and state that contains the FlatList component (presentation, stateless), which again contains a custom presentation string.
Container
Custom list component that includes the FlatList component
(presentational, stateless) and the renderRow method
Custom row (presentational, stateless)
The container includes this component:
<CustomList
items={this.props.viewer}
onCategoryChosen={this._onCategoryChosen}
selectedCategory={this.state.report.selectedCategory}
/>
CustomList:
class CustomList extends Component {
_renderRow = ({ item }) => {
return (
<CustomListRow
item={item.node}
selectedCategory={this.props.selectedCategory}
onPressItem={this.props.onCategoryChosen}
/>
);
};
render() {
return (
<View style={_styles.container}>
<FlatList
data={this.props.items.categories.edges}
renderItem={this._renderRow}
horizontal={true}
keyExtractor={(item, index) => item.node.id}
randomUpdateProp={this.state.updated}
/>
</View>
);
}
}
( )
:
render() {
const idsMatch = this.props.selectedCategory.id == this.props.item.id;
return (
<TouchableHighlight onPress={this._onItemPressed}>
<View style={_styles.root}>
<View style={[
_styles.container,
{ backgroundColor: this._getBackgroundColor() },
]}>
{idsMatch &&
<Image
style={_styles.icon}
source={require('./../../res/img/asd.png')}
/>}
{!idsMatch &&
<Image
style={_styles.icon}
source={require('./../../res/img/dsa.png')}
/>}
<Text style={_styles.text}>
{capitalizeFirstLetter(this.props.item.name)}
</Text>
</View>
<View style={_styles.bottomView}>
<View style={_styles.greyLine} />
</View>
</View>
</TouchableHighlight>
);
}
, , , .
:
_onCategoryChosen = category => {
var oldReportCopy = this.state.report;
oldReportCopy.selectedCategory = category;
this.setState(Object.assign({}, this.state, { report: oldReportCopy }));
};
:
state = {
...
report: defaultStateReport,
};
const defaultStateReport = {
selectedCategory: {
id: 'some-long-od',
name: '',
},
...
};