Using FlatList with item component wrapped with react-redux connect()
See original GitHub issueDescription
I’ve followed the guide at https://facebook.github.io/react-native/docs/flatlist.html to implement a FlatList. My implementation is essentially the same as the example provided in this guide under “More complex example”, except that my <MyListItem />
component has been wrapped with the react-redux
connect()
function in order to pass down some additional props to the component (some props from state, and some props that are functions that use dispatch
). This seems to be working correctly, however the docs don’t make it clear whether this pattern is okay. Will this cause any issues with FlatList?
Sample Code
Here’s the example from the FlatList guide, modified to demonstrate how I’m wrapping my item component with connect()
.
class MyListItem extends React.PureComponent {
_onPress = () => {
this.props.onPressItem(this.props.id);
this.props.myClickHandler(this.props.myProp);
};
render() {
return (
<SomeOtherWidget
{...this.props}
onPress={this._onPress}
/>
)
}
}
MyListItem = connect(state => ({
myProp: state.myProp,
}), {
myClickHandler,
})(MyListItem);
class MyList extends React.PureComponent {
state = {selected: (new Map(): Map<string, boolean>)};
_keyExtractor = (item, index) => item.id;
_onPressItem = (id: string) => {
// updater functions are preferred for transactional updates
this.setState((state) => {
// copy the map rather than modifying state.
const selected = new Map(state.selected);
selected.set(id, !selected.get(id)); // toggle
return {selected};
});
};
_renderItem = ({item}) => (
<MyListItem
id={item.id}
onPressItem={this._onPressItem}
selected={!!this.state.selected.get(item.id)}
title={item.title}
/>
);
render() {
return (
<FlatList
data={this.props.data}
extraData={this.state}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
/>
);
}
}
Solution
Clarify whether this pattern would cause any issues. It’s my understanding that ListView (which FlatList replaces) had some optimisation techniques where the React Components that correspond with the items in the list (one Component per item) are not fully deleted/recreated from memory when they come in to the visible area of the screen (or leave this area), and instead the same Components that have already been rendered are retained in memory and injected with the new props of the new list item. Assuming this is correct and that this sort of optimisation is still being done in FlatList, I’m unsure whether this optimisation technique (or any other implementation detail of FlatList) would conflict with using connect()
to wrap the FlatList item component.
Additional Information
- React Native version: 0.45.1
- Platform: Both
- Development Operating System: macOS
- Build tools: Xcode 8
Issue Analytics
- State:
- Created 6 years ago
- Reactions:4
- Comments:7 (2 by maintainers)
Top GitHub Comments
This is not working if the data needed by MyListItem is not already in the redux state. Imagine that in MyListem item you have to call a function to explicitly load this data.
The action will be executed but when the data is pushed in the redux store, MyListItem is not re-rendered because it is a PureComponent. componentWillUpdate and componentWillReceiveProps are not fired.
You must find a way to tell Flatlist to explicitly re-render this component.
I am facing this issue actually and I will post a solution if I find one 😃
@rmkpatchaa I finally solved the problem by passing
extraData={this.props}
into the flat list, see this for more details.