Kishan Bharda
Kishan Bharda

Reputation: 5690

Conditionally style not working in react native

I followed this answer to dynamically style my component.

Here is my render method :

  render() {
    return (
      <View style={styles.container}>
        <FlatList
          data={this.state.images}
          numColumns={2}
          keyboardShouldPersistTaps={'always'}
          keyboardDismissMode={'on-drag'}
          keyExtractor={item => item.localIdentifier}
          renderItem={({ item, index }) =>

            <TouchableHighlight
              underlayColor='transparent'
              onPress={() => this.openImage(index)}
              onLongPress={() => this.startSelection(item)}
            >
              <View style={[styles.albumContainer, (this.state.selectedItems.indexOf(item)>-1)?styles.selectedItem:styles.unselectedItem]}>
                <Image
                  style={styles.albumThumbnail}
                  source={item.image}
                />
              </View>
            </TouchableHighlight>
          }
        />
      </View>
    );
  }

As you can see I am displaying image thumbnail with TouchableHighlight and FlatList. When user will press and hold on any image thumbnail I called startSelection() with particular flatlist item which then add that item to state. I used that state to set style dynamically of my image as :

<View style={[styles.albumContainer, (this.state.selectedItems.indexOf(item)>-1)?styles.selectedItem:styles.unselectedItem]}>
    <Image
        style={styles.albumThumbnail}
        source={item.image}
    />
</View>

Here is startSelection() method :

  startSelection(item) {
    let temp = this.state.selectedItems;
    temp.push(item);
    this.setState({
      selectedItems : temp
    });
  }

Here is my stylesheet :

const styles = StyleSheet.create({
  selectedItem: {
    borderWidth: 3,
    borderColor: '#22aaff',
  },
  unselectedItem: {
    borderColor: '#000000',
  }
});

But when user press and hold that view, item will added to state but style is not changing. Please help me what's going wrong here !!!

Upvotes: 2

Views: 1370

Answers (2)

Vinicius
Vinicius

Reputation: 1365

This can be found on FlatList docs:

This is a PureComponent which means that it will not re-render if props remain shallow-equal. Make sure that everything your renderItem function depends on is passed as a prop (e.g. extraData) that is not === after updates, otherwise your UI may not update on changes. This includes the data prop and parent component state.

So you can add extraData to your FlatList component like this:

  1. FlatList Component:

    <FlatList
      data={this.state.images}
      extraData={this.state} //add this!
      numColumns={2}
      keyboardShouldPersistTaps={'always'}
      keyboardDismissMode={'on-drag'}
      keyExtractor={item => item.localIdentifier}
      renderItem={({ item, index }) =>
    
        <TouchableHighlight
          underlayColor='transparent'
          onPress={() => this.openImage(index)}
          onLongPress={() => this.startSelection(item)}
        >
          <View style={[styles.albumContainer, (this.state.selectedItems.indexOf(item)>-1)?styles.selectedItem:styles.unselectedItem]}>
            <Image
              style={styles.albumThumbnail}
              source={item.image}
            />
          </View>
        </TouchableHighlight>
      }
    />
    

P.S: If your component state has variables which should not re-render FlatList, you would be better of using extraData = {this.state.selectedItems}, but then you need to make sure you pass a different reference to selectedItems when you call setState on startSelection. Like this:

startSelection(item) {
  let temp = [...this.state.selectedItems];
  temp.push(item);
  this.setState({
    selectedItems : temp
  });
}

Upvotes: 2

Masuk Helal Anik
Masuk Helal Anik

Reputation: 2283

Wrap them with extra []

style={[styles.albumContainer, [(this.state.selectedItems.indexOf(item)>-1)?styles.selectedItem:styles.unselectedItem]]}

Upvotes: 0

Related Questions