【问题标题】:Change style for only clicked on view not all views更改仅单击视图而不是所有视图的样式
【发布时间】:2019-01-02 03:36:55
【问题描述】:

我有一个 <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"
  }
});

【问题讨论】:

  • 当你做this.setState时,它会重新渲染所有
  • 知道如何避免使用 this.setstate 吗?
  • 你最好使用Flatlist来达到这个目的

标签: javascript css reactjs react-native


【解决方案1】:

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

不要将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提问

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

pressed[i] 在用户第一次点击时最初是undefined。 但是!undefined 返回true,所以pressed[i] 的初始值将是true。

pressed: {} 被初始化为一个对象,只存储需要的数据。
如果它被初始化为数组pressed: [],那么undefined 值会浪费空间。

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

工作演示

【讨论】:

  • 这很漂亮,谢谢@SungKim
  • 虽然 i 变量在 this.state.pressed[i] 中是从哪里得到的
  • @SungKim 您能否在回答中澄清我的疑问?按下是一个对象pressed: {}handlePressedIn 你在做pressed[i] = !pressed[i]; 其中i 是视图的索引......然后它是一个数组......对吗?你返回一个对象数组吗?那么它是如何工作的呢?谢谢
  • @SungKim 说得好!感谢您的澄清
  • 我在博客slightedgecoder.com/2018/07/28/…中进一步解释了它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多