简体   繁体   English

我怎样才能在 axios 的反应中让我的每个测验问题及其在不同页面中的选择

[英]How can I have each of my my quiz questions and their choices in different pages in react by axios

I am very new in React.我对 React 很陌生。 I am preparing a quiz.我正在准备测验。 I have my questions and their choices at the same page.我在同一页面上有我的问题和他们的选择。 What I want is to have each questions with their choices in different pages.我想要的是在不同的页面中让每个问题都有自己的选择。 After a button click to a choice I want to pass to the next page's question.单击按钮选择一个选项后,我想转到下一页的问题。 How can I do that?我怎样才能做到这一点?

import React from "react";
import axios from "axios";

function Question(props) {
  this.state = { questionNumber: 0 };
  let style = {
    margin: "5px"
  };
  clickHandler = () => {};

  return (
    <div className="Question">
      <h4>{props.question}</h4>
      <ul>
        {props.choices.map((c, i) => (
          <button style={style} clickHandler={this.clickHandler}>
            {c.choice}
          </button>
        ))}
      </ul>
    </div>
  );
}

class QuizApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = { questions: [], choices: [] };
  }

  componentDidMount() {
    axios
      .get(
        "https://private-anon-c06008d89c-quizmasters.apiary-mock.com/questions"
      )
      .then(response => {
        this.setState({ questions: response.data });
      });
  }

  render() {
    return <div>{this.state.questions.map(q => new Question(q))}</div>;
  }
}

Not quite different pages, but you can use the array of questions and answers to give the illusion of different pages, but all in the same component.不是完全不同的页面,但您可以使用一系列问题和答案来提供不同页面的错觉,但都在同一个组件中。 Just display one element at a time.一次只显示一个元素。 For example, say response.data from your get request is as follows:例如,假设您的 get 请求中的response.data如下:

[
  {
    question: 'What is question 1?',
    option1: 'Option 1',
    option2: 'Option 2',
    option3: 'Option 3'
  },
  {
    question: 'What is question 2?',
    option1: 'Option 1',
    option2: 'Option 2',
    option3: 'Option 3'
  },
  {
    question: 'What is question 3?',
    option1: 'Option 1',
    option2: 'Option 2',
    option3: 'Option 3'
  },
]

You want to display one index of that arrat ay a time, so you will need another state attribute called currentQuestionIndex .您希望每次都显示该 arrat 的一个索引,因此您需要另一个名为currentQuestionIndex状态属性。 Start that with 0, so that it can start at the first question from that array.从 0 开始,以便它可以从该数组的第一个问题开始。

You also need somewhere to store your answers as you go, so, we'll add an answers state attribute.您还需要在某个地方存储您的答案,因此,我们将添加一个answers状态属性。 Both of these should be defined in the constructor, which will now look like this:这两个都应该在构造函数中定义,现在看起来像这样:

  constructor (props, context) {
    super(props, context)
    this.state = {
      currentQuestionIndex: 0,
      questions: [],
      answers: []
    }
  }

The questions state attribute needs to be set in your componentDidMount , so that part in your code looks good so far.需要在您的componentDidMount设置questions状态属性,以便您的代码中的部分到目前为止看起来不错。

We set up the render part so that it only displays whatever question is on the currentQuestionIndex .我们设置了渲染部分,以便它只显示currentQuestionIndex上的任何问题。 I will also already add the Next button so you can navigate to the next question.我还将添加“下一步”按钮,以便您可以导航到下一个问题。

It should look something like this:它应该是这样的:

  render() {
    const { questions, currentQuestionIndex, answers } = this.state

    const { question, option1, option2, option3} = questions[currentQuestionIndex]

    return (<div>
        <h4>{question}</h4>

          <label>
            <input type='radio'
              value={option1}/>
            {option1}
          </label>
        <br/>

          <label>
            <input type='radio'
              value={option2}/>
            {option2}
          </label>
          <br/>
          <label>
            <input type='radio'
              value={option3}/>
            {option3}
          </label>
        <hr/>
        <button>Next</button>
      </div>);
  }

Cool!凉爽的! Now we need to make this radio input buttons actually work by adding the checked prop and adding a handler.现在我们需要通过添加checked prop并添加处理程序来使这个单选输入按钮实际工作。 This is where our answers state comes into play.这就是我们的answers状态发挥作用的地方。 The checked prop is a boolean, so we want a radio button to be checked whenever their current value is in the same index they are in the answers array.checked道具是一个布尔值,所以我们想要一个单选按钮,只要它们的当前值与它们在answers数组中的索引相同,就会被检查。 So this is what our handler will look like:所以这就是我们的处理程序的样子:

onChangeOption (value) {
    const { currentQuestionIndex } = this.state
    let answers = [...this.state.answers]
    answers[currentQuestionIndex] = value

    this.setState({answers}) 
  }

Lets update our render function to incorporate the checked prop and the onChangeOption function:让我们更新我们的渲染函数以合并checked prop 和onChangeOption函数:

  render() {
    const { questions, currentQuestionIndex, answers } = this.state

    const { question, option1, option2, option3} = questions[currentQuestionIndex]

    return (<div>
        <h1>Question {currentQuestionIndex + 1}</h1>
        <h4>{question}</h4>

          <label>
            <input type='radio'
              checked={answers[currentQuestionIndex] === option1}
              value={option1}
              onChange={(evt) => this.onChangeOption(evt.target.value)}/>
            {option1}
          </label>
        <br/>

          <label>
            <input type='radio'
              checked={answers[currentQuestionIndex] === option2}
              value={option2}
              onChange={(evt) => this.onChangeOption(evt.target.value)}/>
            {option2}
          </label>
          <br/>
          <label>
            <input type='radio'
              checked={answers[currentQuestionIndex] === option3}
              value={option3}
              onChange={(evt) => this.onChangeOption(evt.target.value)}/>
            {option3}
          </label>
        <hr/>
        <button>Next</button>
      </div>);
  }

That should take care of our question handling in that page.这应该照顾我们在该页面中的问题处理。 But how should we change the page?但是我们应该如何更改页面呢? Lets work on that Next button, shall we?让我们处理下一个按钮,好吗?

As mentioned previously, what defines what question is displayed is through it's index using the currentQuestionIndex , so upon clicking on the next button, lets increment that.如前所述,定义显示的问题是通过使用currentQuestionIndex的索引,因此在单击下一个按钮时,让我们增加它。 Here is the onClick handler:这是 onClick 处理程序:

  handleNext () {
     let incrementCurrentQuestionIndex = this.state.currentQuestionIndex + 1
     this.setState({currentQuestionIndex: incrementCurrentQuestionIndex})
  }

This is what the next button should look like:这是下一个按钮的样子:

<button onClick={() => this.handleNext()}>Next</button>

Finally, lets add a few final touches so that this little app can function properly:最后,让我们添加一些最后的修饰,以便这个小应用程序能够正常运行:

1- Since you are only getting your questions on the componentDidMount lifecycle method you will need to add a placeholder while your questions are still loading. 1- 由于您只收到有关componentDidMount生命周期方法的问题,因此您需要在问题仍在加载时添加占位符。 So inside the render() method, before rendering your questions, you want to check to see if the questions state is already filled in. Something like this:所以在render()方法中,在呈现你的问题之前,你想检查一下questions状态是否已经填写。像这样:

render() {
    const { questions, currentQuestionIndex, answers } = this.state

    // Will be rendered before you grab all your questions
    if (!questions.length) {
      return <div> Loading questions...</div>
    }

    // Do the rest...
  }

2- Next, you may want to disable the Next button once your array is at it's end. 2-接下来,一旦您的阵列结束,您可能想要禁用“下一步”按钮。 Of course in your actual app, you will handle it differently, but you need to make sure you don't pass the size of the questions array.当然,在您的实际应用程序中,您会以不同的方式处理它,但您需要确保不传递问题数组的大小。 For this example, we just disable the Next button, so it will look like this:在这个例子中,我们只是禁用了 Next 按钮,所以它看起来像这样:

 <button disabled={currentQuestionIndex === questions.length - 1} onClick={() => this.handleNext()}>Next</button>

Update: This had an awkward flow, so for this example, it would probably be better just to display a different page when you run out of questions.更新:这有一个尴尬的流程,所以对于这个例子,当你用完问题时,最好只显示一个不同的页面。 To do this, on your render() function, just add a condition which displays something saying the quiz has ended if the currentQuestionIndex is larger or has reached the size of the questions array.为此,在您的render()函数上,只需添加一个条件,如果 currentQuestionIndex 较大或已达到问题数组的大小,则该条件显示测验已结束。 So something like this BEFORE your questions being rendered:所以在你的问题被呈现之前是这样的:

if (currentQuestionIndex >= questions.length) {
      return (
        <div>
          <h3>End of the Quiz!</h3>
        </div>
      )
    }

The example app has been updated accordingly as well.示例应用程序也已相应更新。

tl;dr: Take advantage of the array of questions you get. tl;dr:利用你得到的一系列问题。 Only display the question and options of the current index you are on.仅显示您所在的当前索引的问题和选项。 When you want to move on the next one, just increment the current index by clicking the button.当您想继续下一个时,只需单击按钮增加当前索引。

Here is the fully functional example app:这是功能齐全的示例应用程序:

 //Simulating data coming from axios const questionsArray = [ { question: 'What is question 1?', option1: 'Option 1', option2: 'Option 2', option3: 'Option 3' }, { question: 'What is question 2?', option1: 'Option 1', option2: 'Option 2', option3: 'Option 3' }, { question: 'What is question 3?', option1: 'Option 1', option2: 'Option 2', option3: 'Option 3' }, ] class App extends React.Component { constructor (props, context) { super(props, context) this.state = { currentQuestionIndex: 0, questions: [], answers: [] } } componentDidMount() { // Do your axios call and set the questions state. // For the sake of simplicity,I'll be using my array. this.setState({questions: questionsArray}) } handleNext () { let incrementCurrentQuestionIndex = this.state.currentQuestionIndex + 1 this.setState({currentQuestionIndex: incrementCurrentQuestionIndex}) } onChangeOption (value) { const { currentQuestionIndex } = this.state let answers = [...this.state.answers] answers[currentQuestionIndex] = value this.setState({answers}) } render() { const { questions, currentQuestionIndex, answers } = this.state if (!questions.length) { return <div> Loading questions...</div> } if (currentQuestionIndex >= questions.length) { return ( <div> <h3>End of the Quiz!</h3> </div> ) } const { question, option1, option2, option3} = questions[currentQuestionIndex] return (<div> <h1>Question {currentQuestionIndex + 1}</h1> <h4>{question}</h4> <label> <input type='radio' checked={answers[currentQuestionIndex] === option1} value={option1} onChange={(evt) => this.onChangeOption(evt.target.value)}/> {option1} </label> <br/> <label> <input type='radio' checked={answers[currentQuestionIndex] === option2} value={option2} onChange={(evt) => this.onChangeOption(evt.target.value)}/> {option2} </label> <br/> <label> <input type='radio' checked={answers[currentQuestionIndex] === option3} value={option3} onChange={(evt) => this.onChangeOption(evt.target.value)}/> {option3} </label> <hr/> <button onClick={() => this.handleNext()}>Next</button> </div>); } } ReactDOM.render( <App />, document.getElementById('app') );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="app"></div>

Take a look at this example:看看这个例子:

https://codesandbox.io/s/km4538r82r https://codesandbox.io/s/km4538r82r

from this lib:从这个库:

react-distributed-forms反应分布形式

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 REXI AXIOS:我正在做一个测验,每个测验在该索引中都有对应的选择数组。 - REACT AXIOS: I am working on a quiz that each questin has corresponding array of choices in that index in 如何使阵列每次运行都能选择不同的选择? - How can I make my array choose different choices each time it runs? 使用 JavaScript,如何在我的测验应用程序上显示一组问题? - Using JavaScript, how can I display a set of questions on my quiz application? 如何在我的测验机器人中显示下一个问题并修复错误? - How can I show the next questions in my quiz bot and fix the error? 如何创建在不同页面上有不同问题的测验? - How to create a quiz that has different questions on different pages? 如何浏览测验中的问题? - How can I navigate questions in a Quiz? 如何防止在我的测验应用程序中更改选项顺序? - How can I prevent changing sequence of options in my quiz app in react? 如何在我的所有网页上显示叠加层? - How can I have an overlay appear on all of my web pages? 我如何在我自己的在线测验中将这个 JS 代码重用于其他问题? 对象? 构架? - How could I reuse this JS code for other questions in my own online quiz? Objects? Frameworks? 如何使用JavaScript将结果显示在性格测验中? - How can I use JavaScript to show results to my personality quiz?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM