Reputation: 4615
I'm building multiple select modal. When user press the item, the item should be marked as 'Checked'.
Problem I added/removed id from id arrays. When I open and check modal, it doesn't show 'Check' sign. But when I close and open the modal again, it shows 'Check' Sign.
To keep track of selected items, I defined the items in the modal component's state.
state = {
selectedSeasonIds: this.props.selectedSeasonIds,
}
Here is react-native-modal which I use to show modal on the screen
<Modal
isVisible={isSelectorVisible}
onBackdropPress = {() => this.props.hideSelector()}>
<View style={styles.modalContainer}>
<FlatList
style={styles.root}
data={this.props.items}
ItemSeparatorComponent={this._renderSeparator}
keyExtractor={this._keyExtractor}
renderItem={this._renderItemForMultiple}/>
</View>
</Modal>
This is render function for each item
_renderItemForMultiple = ({item}) => {
return (
<TouchableOpacity
style={styles.itemStyle}
onPress={() => {this._handleMultipleItemPress(item.id)}}>
<RkText>{item.value}</RkText>
{ this._renderCheck(item.id) } <<< Here is the problem
</TouchableOpacity>
);
}
When user clicks the item, FlatList's item calls _handleMultipleitemPress
_handleMultipleItemPress = (id) => {
let { selectionType } = this.props;
let { selectedSeasonIds, selectedSizeIds, selectedColorIds } = this.state;
if(selectionType===2) {
if(_.includes(this.state.selectedSeasonIds, id)) {
let newSelectedSeasonIds = _.filter(this.state.selectedSeasonIds, (curObject) => {
return curObject !== id;
});
this.setState({selectedSeasonIds : newSelectedSeasonIds});
} else {
let newSelectedSeasonIds = [...this.state.selectedSeasonIds, id];
this.setState({selectedSeasonIds : newSelectedSeasonIds});
}
}
// season Select Action
this.props.seasonSelectAction(id);
}
Problem We added/removed id from id arrays. When I open and check modal, it doesn't show 'Check' sign. But when I close and open the modal again, it shows 'Check' Sign.
Somehow the modal is not rendered even eventhough we setState
in renderCheck()
. Why is it happening? And How can I fix it?
_renderCheck = (id) => {
let { selectionType, selectedSeasonIds, selectedSizeIds, selectedColorIds } = this.props;
if(selectionType===2) {
if(_.includes(this.state.selectedSeasonIds, id)) {
return (<RkText>Check </RkText>);
}
}
return (<RkText> </RkText>);
}
Any other advice will be also appreciated! Thanks for reading this post.
UPDATE I debugged with code and when I press the item, it doesn't go through _renderItemForMultiple
. I think it's because I didn't define a param for _renderItemForMultiple
. How can I pass item to its param? Any idea?
Upvotes: 3
Views: 4101
Reputation: 8640
Even though your state changes, you're not passing it to <FlatList>
, so its props don't change. Its shouldComponentUpdate
method returns false
when none its props change. As the docs state:
By passing
extraData={this.state}
toFlatList
we make sureFlatList
itself will re-render 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.
So you need to pass extraData={this.state}
to FlatList
.
Upvotes: 6