我有一个组件可以从api中获取一个json问题列表。然后每个问题都有5个单选按钮供回答(从 "强烈不同意 "到 "强烈同意")。
这些问题在componentDidMount()中获取,存储在this.state.question中,并在render()中映射到questionComponents。组件(和单选按钮)是通过键来识别的。
我需要在状态中把答案存储为一个数组。这显然必须在handleChange中发生,但我不知道如何做到这一点。我对response很陌生,所以可能有一个比我现在做的更简单的方法来做这件事。
下面是App.js
import React from 'react';
import Question from './Question';
class App extends React.Component {
constructor() {
super()
this.state = {
questions: [],
answers: []
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
const {name, value, type, checked, key} = event.target
this.setState(prevState => {
//
}
}
componentDidMount() {
fetch("http://localhost:7777/api/questions")
.then(response => response.json())
.then(data => {
this.setState({
questions: data
})
})
}
render () {
const questionComponents = this.state.questions.map(question =>
<Question key={question.id} question={question.question} handleChange = {this.handleChange} />)
return (
<div>
<h1> Questions!</h1>
{questionComponents}
</div>
)
}
}
export default App;
和Question.js
import React from "react"
function Question(props) {
return (
<div className="question">
<p>{props.question}</p>
<label>strongly disagree</label>
<input
type="radio"
name={props.key}
key={props.key}
value="1"
onChange={props.handleChange}>
</input>
<label> disagree</label>
<input
type="radio"
name={props.key}
key={props.key}
value="2"
onChange={props.handleChange}>
</input>
<label>no opinion</label>
<input
type="radio"
name={props.key}
key={props.key}
value="3"
onChange={props.handleChange}>
</input>
<label> agree</label>
<input
type="radio"
name={props.key}
key={props.key}
value="4"
onChange={props.handleChange}>
</input>
<label>strongly agree</label>
<input
type="radio"
name={props.key}
key={props.key}
value="5"
onChange={props.handleChange}>
</input>
</div>
)
}
export default Question
这里有一个工作示例。
class App extends React.Component {
constructor() {
super()
this.state = {
questions: [
{
id: '123',
question: 'What?'
},
{
id: '1234',
question: 'When?'
}
],
answers: {}
}
}
handleChange = (event) => { // using an arrow function instead of binding in the constructor
const { name, value } = event.target;
// this will add / update a key-value pair depending if it exists or not
this.setState(state => state.answers[name] = value)
}
componentDidMount() {
// import your data
}
render() {
console.log(this.state.answers)
const { questions } = this.state;
return (
<div>
<h3>Questions</h3>
{questions.map(question => {
return <Question key={question.id} name={question.id} question={question.question} handleChange={e => this.handleChange(e)} />
})}
</div>
);
}
}
function Question(props) {
// create a label array to loop over instead of typing all input fields
const labels = ['strongly disagree', 'disagree', 'no opinion', 'agree', 'strongly agree']
return (
<div className="question">
<p>{props.question}</p>
<div className="inputs">
{labels.map((label, idx) => {
return (
<div key={props.name}>
<label key={label}>{label}</label>
<input
type="radio"
name={props.name}
value={idx + 1}
onChange={event => props.handleChange(event)}
/>
</div>
)
})}
</div>
</div>
)
}
答案存储在一个对象中,而不是数组,因为它更容易管理。你也可以使用数组,但是更新数组有点困难,因为你必须循环处理所有的项目以找到你想要更新的项目。我不知道你的问题对象是什么样子的,所以我临时起意。注意 key
属性被React用来识别从 map
功能。否则不要使用。
希望对大家有所帮助,祝大家好运!