React - 无法修改 object 的 child 属性

React - Cannot modify object's child properties

我有一个名为测验的 object,我可以很好地编辑测验的主要属性。

测验有:标题、时间限制、价值和问题列表 - 由问题 object 组成。

每个问题有 4 个属性:问题(字符串)、值、解释和答案列表

每个答案都有 2 个属性:内容和正确性

我可以毫无问题地修改基本测验属性(标题、时间限制和值)。我还能够显示每个问题并将其传递到模式,它将填充字段,包括答案。

但是,当我尝试修改字段(在问题或答案中)时出现问题,我收到以下错误:

TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))

我猜这是因为我在每个输入上都使用了 onChange 函数,但是这些对编辑测验有用吗?

添加新问题实例时也会出现同样的问题。

我已尝试将所有最少代码包含到 运行

代码:

import 'bootstrap/dist/css/bootstrap.min.css';
import React, {useState, useEffect} from 'react';
import { Modal, Form, Button } from 'react-bootstrap';

export default function EditQuiz(props) {


    const [quiz, setQuiz] = useState({title:"example", timeLimit:300, value:200})

    const [questionList, setQuestionList]=useState( [ 
      { id: 1, question : "question1", value:5, explaination : "answer1", 
      answers: [ {content: "aaa", correct: true},{content: "bbb", correct: false},{content: "ccc", correct: false},{content: "ddd", correct: false}]
    } ,
      { id: 2, question : "question2", value:10, explaination : "answer1", 
      answers: [ {content: "eee", correct: true},{content: "fff", correct: false},{content: "ggg", correct: false},{content: "hhhh", correct: false} ]
      }
    ])

    const [submitQuiz, setSubmitQuiz] = useState(false);
    const [executedSet, setExecutedSet] = useState(false);
  
    const [missingParentData, setMissingParentData] = useState();
  
    useEffect(() => {
      if (props.location.state){
        setQuiz(props.location.state)
        setQuestionList(props.location.state.questions)
        setExecutedSet(true)    
      }
      else{
        setMissingParentData(true)
      }
      console.log(quiz)
    },[]) 

  const addQuestionButton = () => {
    setQuestion({question: "", value:0, explaination: "", answers :  [ {content: "", correct: false},{content: "", correct: false},{content: "", correct: false},{content: "", correct: false} ] })
    setShow(true)
  };

  const editQuestionButton = (question) =>{
    console.log(question)
    setQuestion(question)
    setShow(true)
  }

 
  const printQuizButton = () => {
    console.log(quiz)
  };

  const [value, setValue] = useState(0);
  const [show, setShow] = useState(false);
  const [correct, setCorrect] = useState(false);
  const [explaination, setExplaination] = useState("");
  const [question, setQuestion]=useState('')

  const [dropdown, setDropdown]=useState("")

    return (
    <div className='page'>
      <br/>
      <h1>Quiz input / Edit Page</h1>
      <br/><br/><br/>
      <h2>Quiz</h2>
      <form action="">
        <label htmlFor="Title">Title</label>
        <br/>
        <input type="text" id="title" name="title" value={ quiz ? quiz.title : ''} onChange={(e)=>setQuiz({...quiz, title: e.target.value})}/>
        <br/>
        <label htmlFor="Time-limit">Time limit (seconds)</label>
        <br/>
        <input type="number" id="Time-limit" name="Time-limit" value={quiz ? quiz.timeLimit : ''} onChange={(e)=>setQuiz({...quiz, timeLimit: e.target.value})}/>
        <br/>
        <label htmlFor="Value">Value</label>
        <br/>
        <input type="number" id="Value" name="Value" value={quiz ? quiz.value : ''} onChange={(e)=>setQuiz({...quiz, value: e.target.value})}/>
        <br/><br/>
        <input type="submit" className="Send-Message-CTA shadow" value="Submit Quiz"/>
      </form>

      <h2>Questions</h2>
      
      <button onClick={()=> printQuizButton()}>print Quiz</button>   
      <button onClick={()=> addQuestionButton()}>Add Question</button>   

      {questionList.map((question, index)=>(
          <div key={index}>
            ID: {question.id} Question: {question.question}
            <br/>
            <button onClick={()=> editQuestionButton(question)}>Edit Question</button>  
            <br/>
            <br/>
            
          </div>
      ))}

    <Modal show={show} backdrop="static" keyboard={false} state={question ? question : ""}>

      <Modal.Header>
        <Modal.Title>Adding Question Form</Modal.Title>
      </Modal.Header>

      <Modal.Body>
        <Form>
          <div className="form-group">
            <label htmlFor="question">Question</label>
            <input value={question ? question.question: ''} onChange={(e)=>setQuestion(...question, e.target.value)} type="text" 
            className="form-control stuff" id="question" placeholder="Enter question name" required/>
          </div>

          <div className="form-group">
            <label htmlFor="value">Value</label>
            <input value={question ? question.value: ''} onChange={(e)=>setQuestion(...question, e.target.value)} type="number" className="form-control stuff" id="value" required/>
          </div>

          <div className="form-group">
            <label htmlFor="explaination">Explaination</label>
            <input value={question ? question.explaination: ''} onChange={(e)=>setQuestion(...question, e.target.value)} type="text" 
            className="form-control stuff" id="explaination" placeholder="Enter Correct Explaination" required/>
          </div>
          <br/>
          You may enter up to 4 answers below:
          <br/>
          (Leave blank if un-wanted, requires atleast 2)
          <br/><br/>

          { question.answers ? question.answers.map((answer, index)=>(
          <div key={index}>
            <div className="form-group">
              <label htmlFor="explaination">Answer {index + 1}</label>
               
                {/* <input onChange={ (e) => setAnswers(prevAnswers => { prevAnswers[index] = e.target.value; return prevAnswers; })} value={ answer ? answer.content : ''} type="text" className="form-control stuff" id="explaination" placeholder="Enter answer display words" required/> */}
               
               
              <input onChange={ (e) => setQuestion ( ...question, e.target.value )} value={ answer ? answer.content : ''} type="text" 
              className="form-control stuff" id="explaination" placeholder="Enter answer display words" required/>

            </div>
          </div>
          )) : <br/> }

        </Form>
      </Modal.Body>

      <Modal.Footer>
        <Button type="submit" className="btn btn-dark" onClick={()=> setShow(false)}> Close </Button>
       

    </Modal>

    </div>);

}
setQuestion(...question, e.target.value)

应该是

setQuestion({...question, explanation: e.target.value})