更改样式仅适用于单击的视图而不是所有视图

时间:2018-07-25 10:37:39

标签: javascript css reactjs react-native

我有一个<TouchableWithoutFeedback>包裹在一个封闭视图周围,我想在单击onPressIn时更改该封闭视图的颜色,但是所有视图的颜色都会改变,我的意思是映射视图,请问如何让onPressIn更改仅特定视图的样式,而不是全部更改

const herbs = this.state.record.map(herb => (
  <TTouchableWithoutFeedback
    onPressIn={() => this.setState({ pressed: !this.state.pressed })}
    key={herb.id}
  >
    <View style={this.state.pressed ? BackStyles.herbBox : BackStyles.herb_box}>
      <Image
        style={BackStyles.image}
        source={{ uri: `${herb.name.replace(/ /g, "")}` }}
      />
      <View style={{ flexDirection: "column" }}>
        <Text style={BackStyles.header}>{herb.name}</Text>
        <Text style={BackStyles.sub}>{herb.bot}</Text>
      </View>
    </View>
  </TTouchableWithoutFeedback>
));

const BackStyles = StyleSheet.create({
  herb_box: {
    backgroundColor: "#fff",
    borderRadius: 7,
    marginTop: 10,
    marginBottom: 10,
    flexDirection: "row",
    width: "95%",
    alignSelf: "center"
    //   height: '2%'
    //  justifyContent: 'center',
  },
  herbBox: {
    backgroundColor: "#28B564",
    borderRadius: 7,
    marginTop: 10,
    marginBottom: 10,
    flexDirection: "row",
    width: "95%",
    alignSelf: "center"
  }
});

1 个答案:

答案 0 :(得分:5)

您必须跟踪通过TTouchableWithoutFeedback创建的每个map组件的布尔状态。

pressed设为布尔值,而不是使其成为对象来跟踪每个组件。

与此类似的东西。

class App extends Component {
  state = {
    pressed: {}
  };

  handlePressedIn = i => {
    this.setState(prevState => {
      const pressed = { ...prevState.pressed };
      pressed[i] = !pressed[i];
      return { pressed };
    });
  };

  render() {
    const herbs = this.state.record.map((herb, i) => (
      <TTouchableWithoutFeedback
        onPressIn={() => this.handlePressedIn(i)}
        key={herb.id}
      >
        <View
          index={i}
          style={
            this.state.pressed[i] === i && this.state.pressed
              ? BackStyles.herbBox
              : BackStyles.herb_box
          }
        >
          <Image
            style={BackStyles.image}
            source={{ uri: `${herb.name.replace(/ /g, "")}` }}
          />
          <View style={{ flexDirection: "column" }}>
            <Text style={BackStyles.header}>{herb.name}</Text>
            <Text style={BackStyles.sub}>{herb.bot}</Text>
          </View>
        </View>
      </TTouchableWithoutFeedback>
    ));
    return <div>{herbs}</div>;
  }
}

更新

这里是对代码的工作原理的补充说明。
@Aravind S

询问
  

您能否在回答中澄清我的疑问?按下是一个对象   按下:{},并在handlePressedIn中进行按下[i] =   !pressed [i];其中我是视图的索引...它是一个数组   那...对吗?您是否返回对象数组?那么它如何运作?

用户第一次点击时,

pressed[i]最初是undefined。 但是!undefined返回true,因此pressed[i]的初始值为true。

pressed: {}被初始化为仅存储所需数据的对象。
如果将其初始化为数组pressed: [],则会浪费undefined值的空间。

基本上return { clicked }返回以位置(索引)为键的对象/字典。

enter image description here

工作演示

Edit so.answer.51516825