首页 > 解决方案 > React-native: how to highlight a flatlist item when it is touched

问题描述

I have a flatlist and I want a background color to appear on an item in the list when it is touched. See image below; this is what should happen if I touch "game_name3":

enter image description here

But nothing happens; it stays looking like the screen on the left.

Here is my code:

constructor (props) {
    super(props);
    this.state = {
        ...
        game_names: [
            {game_name:"game_name1", players:4},
            {game_name:"game_name2", players:4},
            {game_name:"game_name3", players:4},
            {game_name:"game_name4", players:4},
            {game_name:"game_name5", players:4},
            {game_name:"game_name6", players:4},
        ],
        game_selected: '',
        ...
    }
}
...
selectPublicGame = (game) => {
    this.setState({game_selected: game});
}

renderItem = ({item}) => {
  const unselected_game =
  <View style={{flexDirection: 'row', flex: .5, justifyContent: 'space-between'}}>
    <Text style={[styles.listText, styles.textPaddingHorizontal]}>
      {item.game_name}
    </Text>
    <Text style={[styles.listText, styles.textPaddingHorizontal]}>
      ({item.players}/6)
    </Text>
  </View>;

  const selected_game =
  <View style={{flexDirection: 'row', flex: .5, justifyContent: 'space-between', backgroundColor: colors.JBTealTrans}}>
      <Text style={[styles.listText, styles.textPaddingHorizontal]}>
        {item.game_name}
      </Text>
      <Text style={[styles.listText, styles.textPaddingHorizontal]}>
      ({item.players}/6)
    </Text>
  </View>;

  let selection;

  if (item.game_name == this.state.game_selected) {
      selection = selected_game
  } else {
      selection = unselected_game
  }

  return (
    <TouchableWithoutFeedback
      onPress={() => this.selectPublicGame(item.game_name)}
    >
      {selection}
    </TouchableWithoutFeedback>
  )
}
...
render() {
  ...
  return(
    ...
    <FlatList
      data={this.state.game_names}
      renderItem={this.renderItem}
      keyExtractor={(item, index) => index.toString()}
    />
    ...
  )
}
...

Each item in the flatlist is wrapped in TouchableWithoutFeedback, onPress sets the game_selected state to the game name that was selected. The items are conditionally rendered. If the game name is the same as the game_selected state, it should render the "selected_game" constant, which has the backgroundColor style, but is not doing anything for some reason.

标签: react-native

解决方案


FlatListdata是一个纯组件,只有在对其或extraDataprops的严格相等检查返回时才会重新渲染false。由于您的组件渲染依赖于state.game_selected它,因此需要包含在extraData

<FlatList
      data={this.state.game_names}
      renderItem={this.renderItem}
      keyExtractor={(item, index) => index.toString()}
      extraData={this.state.game_selected}
    />

推荐阅读