[英]REACT AXIOS: I am working on a quiz that each questin has corresponding array of choices in that index in
[英]How can I have each of my my quiz questions and their choices in different pages in react by axios
我對 React 很陌生。 我正在准備測驗。 我在同一頁面上有我的問題和他們的選擇。 我想要的是在不同的頁面中讓每個問題都有自己的選擇。 單擊按鈕選擇一個選項后,我想轉到下一頁的問題。 我怎樣才能做到這一點?
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>;
}
}
不是完全不同的頁面,但您可以使用一系列問題和答案來提供不同頁面的錯覺,但都在同一個組件中。 一次只顯示一個元素。 例如,假設您的 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'
},
]
您希望每次都顯示該 arrat 的一個索引,因此您需要另一個名為currentQuestionIndex
狀態屬性。 從 0 開始,以便它可以從該數組的第一個問題開始。
您還需要在某個地方存儲您的答案,因此,我們將添加一個answers
狀態屬性。 這兩個都應該在構造函數中定義,現在看起來像這樣:
constructor (props, context) {
super(props, context)
this.state = {
currentQuestionIndex: 0,
questions: [],
answers: []
}
}
需要在您的componentDidMount
設置questions
狀態屬性,以便您的代碼中的部分到目前為止看起來不錯。
我們設置了渲染部分,以便它只顯示currentQuestionIndex
上的任何問題。 我還將添加“下一步”按鈕,以便您可以導航到下一個問題。
它應該是這樣的:
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>);
}
涼爽的! 現在我們需要通過添加checked
prop並添加處理程序來使這個單選輸入按鈕實際工作。 這就是我們的answers
狀態發揮作用的地方。 被checked
道具是一個布爾值,所以我們想要一個單選按鈕,只要它們的當前值與它們在answers
數組中的索引相同,就會被檢查。 所以這就是我們的處理程序的樣子:
onChangeOption (value) {
const { currentQuestionIndex } = this.state
let answers = [...this.state.answers]
answers[currentQuestionIndex] = value
this.setState({answers})
}
讓我們更新我們的渲染函數以合並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>);
}
這應該照顧我們在該頁面中的問題處理。 但是我們應該如何更改頁面呢? 讓我們處理下一個按鈕,好嗎?
如前所述,定義顯示的問題是通過使用currentQuestionIndex
的索引,因此在單擊下一個按鈕時,讓我們增加它。 這是 onClick 處理程序:
handleNext () {
let incrementCurrentQuestionIndex = this.state.currentQuestionIndex + 1
this.setState({currentQuestionIndex: incrementCurrentQuestionIndex})
}
這是下一個按鈕的樣子:
<button onClick={() => this.handleNext()}>Next</button>
最后,讓我們添加一些最后的修飾,以便這個小應用程序能夠正常運行:
1- 由於您只收到有關componentDidMount
生命周期方法的問題,因此您需要在問題仍在加載時添加占位符。 所以在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 按鈕,所以它看起來像這樣:
<button disabled={currentQuestionIndex === questions.length - 1} onClick={() => this.handleNext()}>Next</button>
更新:這有一個尷尬的流程,所以對於這個例子,當你用完問題時,最好只顯示一個不同的頁面。 為此,在您的render()
函數上,只需添加一個條件,如果 currentQuestionIndex 較大或已達到問題數組的大小,則該條件顯示測驗已結束。 所以在你的問題被呈現之前是這樣的:
if (currentQuestionIndex >= questions.length) {
return (
<div>
<h3>End of the Quiz!</h3>
</div>
)
}
示例應用程序也已相應更新。
tl;dr:利用你得到的一系列問題。 僅顯示您所在的當前索引的問題和選項。 當您想繼續下一個時,只需單擊按鈕增加當前索引。
這是功能齊全的示例應用程序:
//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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.