管理与动态生成的表单反应的状态
managing state in react with dynamically generated form
我有一个组件可以从 api 中获取 json 个问题列表。然后每个问题都有 5 个单选按钮供回答(从 "strongly disagree" 到 "strongly agree")。
问题在 componentDidMount() 中获取,存储在 this.state.questions 中,并映射到 render() 中的 questionComponents。组件(和单选按钮)由键标识。
我需要将答案作为数组存储在状态中。这显然必须在 handleChange 中发生,但我不知道该怎么做。我对反应还很陌生,所以可能有比我现在正在做的更简单的方法来做到这一点。
这是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>
)
}
答案存储在对象而不是数组中,因为它更易于管理。您也可以使用数组,但更新它有点困难,因为您必须遍历所有项目才能找到要更新的项目。
我不知道你的问题对象是什么样的,所以我即兴创作了。
请注意,React 使用 key
属性来标识从 map
函数返回的元素。否则不要使用它。
希望对您有所帮助,祝您好运!
我有一个组件可以从 api 中获取 json 个问题列表。然后每个问题都有 5 个单选按钮供回答(从 "strongly disagree" 到 "strongly agree")。
问题在 componentDidMount() 中获取,存储在 this.state.questions 中,并映射到 render() 中的 questionComponents。组件(和单选按钮)由键标识。
我需要将答案作为数组存储在状态中。这显然必须在 handleChange 中发生,但我不知道该怎么做。我对反应还很陌生,所以可能有比我现在正在做的更简单的方法来做到这一点。
这是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>
)
}
答案存储在对象而不是数组中,因为它更易于管理。您也可以使用数组,但更新它有点困难,因为您必须遍历所有项目才能找到要更新的项目。
我不知道你的问题对象是什么样的,所以我即兴创作了。
请注意,React 使用 key
属性来标识从 map
函数返回的元素。否则不要使用它。
希望对您有所帮助,祝您好运!