子组件文本框默认值未更新

时间:2021-06-28 20:48:11

标签: reactjs react-hooks

我有一系列问题和一个文本框来获取答案。我希望每次单击下一个按钮进入下一个时,文本框都有一个空白的默认值,但它始终具有我提交的最后一个答案的值。我已经看过更改子组件中的状态,但这似乎并没有做到,并且希望得到任何建议/想法?代码如下:

  // function is rendering each question one by one. 
  function generateQuestions() {

    return <Grid container spacing={3}>
              <Grid item xs={12}>
                <QuestionTile 
                  questionNumber={questionNumber}
                  question={currentQuestions[questionNumber].question}
                  answer={currentQuestions[questionNumber].answer}
                  updateUserAnswer={updateUserAnswers}
                  currentUserAnswer={" "}
                  // currentUserAnswers[questionNumber] === null ? " " : currentUserAnswers[questionNumber]
                />
              </Grid>
              <Grid item xs={12}>
                {getNextAndPrevButtons(currentQuestions.length)}
              </Grid>
            </Grid>;
  }

和子组件:

export default function QuestionTile({question, questionNumber, answer, updateUserAnswer, currentUserAnswer}) {
    const classes = useStyles();
    const [userAnswer, setUserAnswer] = useState(currentUserAnswer)

    function updateTextBoxValue(questionNumber, value) {

      console.log("Updating text box value")
      setUserAnswer(value)
      console.log(userAnswer)
      updateUserAnswer(questionNumber, value)
      setUserAnswer(currentUserAnswer)
    }


    return (
        <React.Fragment>
            <Grid container spacing={3} >
              <Grid item xs={12}>
                <Title>{questionNumber + 1}) {question}</Title>
              </Grid>
                <Title>Answer: </Title>
                <TextField
                  id={questionNumber}
                  defaultValue={currentUserAnswer}                
                  type="number"
                  className={classes.basicQuestionPadding}
                  onChange={(event) => updateTextBoxValue(questionNumber, event.target.value)}
                /> 
            </Grid>
        </React.Fragment>
    )
}  

我将用户的答案作为列表存储在父组件的状态中,这是我传递给子组件的函数的代码:

  function updateUserAnswers(questionNumber, answer) {
    currentUserAnswers[questionNumber] = answer
  }

为了完整起见,提交和上一个按钮的代码如下:

 // Store the question number in state to trigger re-render on question change (and hence show new question)
  function getNextAndPrevButtons(numberOfQuestions) {
    if ((questionNumber < (numberOfQuestions-1)) && questionNumber >= 1) {
      return <Grid container direction="row"  spacing={10}>
        <Grid className={classes.QuestionNavButtons} justify="space-between" item xs={5}>
          <Button variant="contained" onClick={() => setQuestionNumber(questionNumber-1)}>Prev</Button>
        </Grid>
        {/* <Grid item xs={6}><div></div></Grid> */}
        <Grid className={classes.QuestionNavButtons} justify="space-between" item xs={5}>
          <Button variant="contained" onClick={() => setQuestionNumber(questionNumber+1)}>Submit</Button>
        </Grid>
      </Grid>;
    } 
   
    if (questionNumber >= 1) {
      return <Grid container direction="row"  spacing={10}>
      <Grid className={classes.QuestionNavButtons} justify="space-between" item xs={5}>
        <Button variant="contained" onClick={() => setQuestionNumber(questionNumber-1)}>Prev</Button>
      </Grid>
      <Grid className={classes.QuestionNavButtons} justify="space-between" item xs={5}>
        <Button variant="contained" onClick={() => setLevel("answers")}>View Answers</Button>
      </Grid>
    </Grid>;    
    }

    if (questionNumber < (numberOfQuestions-1)) {
      return <Button variant="contained" onClick={() => setQuestionNumber(questionNumber+1)}>Next</Button>;
    }
  }

这是我第一次发布关于堆栈溢出的问题,所以如果我遗漏了任何细节,请告诉我。

谢谢!

1 个答案:

答案 0 :(得分:0)

我能够通过向 TextField 元素添加一个 key 属性来回答这个问题,并确保每个问题都会改变它。在这种情况下的答案。这不是最佳,因为它错过了具有相同答案的两个问题的用例(这不会触发重新渲染)。更好的方法可能是传递一个计数器或其他东西。它也可能不是最干净的解决方案,因此在此期间仍然欢迎更好的解决方案。

相关问题