在react中用动态生成的形式管理状态。

问题描述 投票:1回答:1

我有一个组件可以从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
javascript reactjs forms radio-button
1个回答
0
投票

这里有一个工作示例。

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 功能。否则不要使用。

希望对大家有所帮助,祝大家好运!

© www.soinside.com 2019 - 2024. All rights reserved.