如何在React Native中使用onPress道具获得用户的选择

问题描述 投票:0回答:2

今天是个好日子。请问React Native取代React的e.target.innerText是什么?我试图从TouchableOpacity组件中获取用户点击的内容。我正在构建一个React Native测验应用程序。

我使用TouchableOpacity作为选项。我正在使用onPress函数来获取用户点击的选项

<View style={{ flex: 2, flexDirection: 'row', justifyContent: 'space-between' }}>
                    <TouchableOpacity onPress = {(e)=>this.props.onAnswer(e, currentQuestion)}>
                        <View style={{ width: 171.5, height: 100, backgroundColor: 'lightgrey' }}>
                            <Text style={styles.options}>{questions[currentQuestion].options[0]}</Text>
                        </View>
                    </TouchableOpacity>
                    <TouchableOpacity onPress = {(e)=>this.props.onAnswer(e, currentQuestion)}>
                        <View style={{ width: 171.5, height: 100, backgroundColor: 'lightgrey' }}>
                            <Text style={styles.options}>{questions[currentQuestion].options[1]}</Text>
                        </View>
                    </TouchableOpacity>
                </View>
                <View style={{ flex: 2.7, flexDirection: 'row', justifyContent: 'space-between' }}>
                    <TouchableOpacity onPress = {(e)=>this.props.onAnswer(e, currentQuestion)}>
                        <View style={{ width: 171.5, height: 100, backgroundColor: 'lightgrey' }}>
                            <Text style={styles.options}>{questions[currentQuestion].options[2]}</Text>
                        </View>
                    </TouchableOpacity>
                    <TouchableOpacity onPress = {(e)=>this.props.onAnswer(e, currentQuestion)}>
                        <View style={{ width: 171.5, height: 100, backgroundColor: 'lightgrey' }}>
                            <Text style={styles.options}>
                                {questions[currentQuestion].options[3]}
                            </Text>
                        </View>
                    </TouchableOpacity>
                </View>

所以创建答案功能......如何确定用户是否选择了正确的答案。

onAnswer = () => {
        return (
            ??? === questions[currentQuestion].answer ? this.onCorrect() : this.onWrong()
          )
        }


如果它是React,我已经取代了'???'到e.target.innerText

请帮帮我。

reactjs react-native javascript-framework
2个回答
0
投票

编辑:

我在下面的原始答案类似于你所拥有的。所以,只需编辑你的onPress方法,如下所示:

onPress = {(e)=>this.props.onAnswer(currentQuestion, questions[currentQuestion].options[0])}

并且您的onAnswer将能够针对每个问题回答用户:

onAnswer(question, usersAnswer) {
  ..
}

render() { ... }

**


大多数情况下,反应组件应该由数据或状态和道具驱动(您不希望通过使用纯JS或JQuery依赖DOM元素来使用您的逻辑)。

为此,您需要一个如下的反应解决方案:

...
  state = {
    data: [{
      id: 1,
      name: 'Anna'
    },
    {
      id: 2,
      name: 'John'
    },
    {
      id: 3,
      name: 'James'
    },
    {
      id: 4,
      name: 'John'
    }]
  }
  onPersonPress(person) {
    console.log("e is ", person);
  }

  render() {
    const { data = [] } = this.state;
    return (
      <View>
        {data.map(person => {
          return (<TouchableOpacity onPress={(e) => this.onPersonPress(person)}>
            <View><Text>Click Me - {person.name}</Text></View>
          </TouchableOpacity>)
        })}
      </View>
    )
  }
  ...

这是处理这类问题的最常见方式之所以是因为它具有灵活性,而且可能是最符合逻辑的。有了这个,你可以使用标识符(id)或任何字段,而不是强制使用Text显示的'innerText',它并不总是唯一的(在我的情况下,还有另一个John)

P.S:其他人不喜欢这种实现,因为性能考虑因素onPress={(e) => this.onPersonPress(person)}所以还有其他方法可以达到同样的效果。


0
投票

试试这个:

import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';

const questions = [
  {
    question: 'question1 ?',
    options: ['option1', 'option2', 'option3'],
    answer: 'option2',
    score: 10,
  },
  {
    question: 'question2 ?',
    options: ['option1', 'option2', 'option3'],
    answer: 'option1',
    score: 10,
  },
  {
    question: 'question3 ?',
    options: ['option1', 'option2', 'option3'],
    answer: 'option3',
    score: 10,
  },
];

class QuizQuestion extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      totalScore: 0,
      answered: questions.map(() => false), // All questions' answered state = false at statup
    };
  }

  render() {
    return (
      <View
        style={{
          flex: 2,
          flexDirection: 'row',
          justifyContent: 'space-between',
        }}
      >
        {questions.map(({
          question, options, answer, score,
        }, index) => (
          <View>
            <View>
              <Text>{question}</Text>
            </View>

            {/* Options  */}
            <View>
              {options.map(({ option }) => (
                <TouchableOpacity
                  onPress={() => {
                    let { totalScore, answered } = this.state;

                    if (!answered[index] && option === answer) {
                      answered[index] = true;
                      this.setState({
                        totalScore: totalScore + score,
                        answered,
                      });
                    }
                  }}
                >
                  <View>
                    <Text>{option}</Text>
                  </View>
                </TouchableOpacity>
              ))}
            </View>
          </View>
        ))}
      </View>
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.