onPress 事件仅采用数组的最后一个索引 - React Native

onPress event only takes last index of array - React Native

在您将此问题标记为关闭问题或事件绑定问题的重复之前,请知道我已经尝试了所有这些问题,但都没有用。

A working demo of the issue.打开link。 运行 android 上的项目并检查日志。如果您单击第一个问题中的任何选项,它将记录 lastIndex(这里是 4。因为总共有 5 个问题)当它应该记录 firstIndex 时,它是 0.

所以我正在使用 javascript map 来遍历我的问题数组和 return 问题及其各自的选项。在里面我有另一个 map 来循环选项。

复选框是一个 react-native-elements 组件。

  renderCard = (item, index) => {
    return (
      <Card style={styles.testCard}>
        <View key={item.u_question_id}>
          <Text style={styles.question}>{index + 1}. {item.question}</Text>
          {item.options.map(({ option, checked }, i) => {
            return (
              <View key={i}>
                <CheckBox
                  containerStyle={{ backgroundColor: "transparent", borderWidth: 0 }}
                  title={option}
                  checkedIcon='dot-circle-o'
                  uncheckedIcon='circle-o'
                  checked={checked}
                  onPress={() => this.onSelectOption(index, i)}
                />
              </View>
            )
          })}
        </View>
      </Card>
    )
  }

我期望的是复选框的 onPress 应该将 questionIndexoptionIndex 发送到 onSelectOption 以更改状态和视图,但是 onPress 总是发送问题数组的最后一个索引,因此最后一个问题的选项会发生变化,而不是预期的选项。

我的onSelectOption方法。这里 questionIndex 如果我有 5 个问题,即使我正在按第一个问题的选项,也会出现 4。

  onSelectOption = (questionIndex, optionIndex) => {
    const selectedLanguageQuestionsCopy = this.state.selectedLanguageQuestions;
    selectedLanguageQuestionsCopy[questionIndex].options.forEach(option => {
      option.checked = false;
    });
    selectedLanguageQuestionsCopy[questionIndex].options[optionIndex].checked = true;
    
    this.setState({ assessmentData: selectedLanguageQuestionsCopy });
  }

我试过使用:

  1. onPress={() => this.onSelectOption(index, i)}

  2. onPress={this.onSelectOption.bind(this, index, i)} 并将 onSelectOption 更改为普通方法而不是数组函数。

但它不起作用。我总是得到问题数组的最后一个索引。

我调用renderCard方法的地方。 selectedLanguageQuestions 是一个对象数组。

<Swipe 
   data={selectedLanguageQuestions}
   activeQuestion={activeQuestion}
   renderCard={(item, i) => this.renderCard(item, i)}
   onSwipeLeft={(ques, i) => this.setState({ activeQuestion: i })}
   onSwipeRight={(ques, i) => this.setState({ activeQuestion: i })}
/>

滑动渲染方法:

render() {
    return (
      <View>
        {this.renderCards()}
      </View>
    );
}

renderCards() {
    return this.props.data.map((item, i) => {
      if (i === this.state.index) {
        return (
          <Animated.View
            key={i}
            style={[this.getCardStyle(), styles.cardStyle]}
            {...this.panResponder.panHandlers}
          >
            {this.props.renderCard(item, i)}
          </Animated.View>
        );
      }

      return (
        <Animated.View 
          key={i} 
          style={[styles.cardStyle, { opacity: 0 }]}
          {...this.panResponder.panHandlers}
        >
          {this.props.renderCard(item, i)}
        </Animated.View>
      )
    });
}

好像在 Swipe.js 第 137 行

return (
     <Animated.View 
       key={i} 
       style={[styles.cardStyle, { opacity: 0 }]}
       {...this.panResponder.panHandlers}
     >
       {this.props.renderCard(item, i)}
     </Animated.View>
)

您将答案保持在彼此之上,所以实际情况是您点击了不透明度为 0 的答案,但因为您看不到它们,所以您认为可见的答案是那些获得事件的答案.所以我建议你禁用不透明度为 0 的答案的事件,如下所示:

return (
    <Animated.View 
       key={i} 
       pointerEvents="none"
       style={[styles.cardStyle, { opacity: 0 }]}
       {...this.panResponder.panHandlers}
    >
       {this.props.renderCard(item, i)}
    </Animated.View>
)

刚刚添加了 pointerEvents="none" 属性;要查看问题如何打断您的“按下”,请将不透明度设置为 0.5 以上,您就会看到问题所在。

希望这能解决您的问题。