我有一系列问题和一个文本框来获取答案。我希望每次单击下一个按钮进入下一个时,文本框都有一个空白的默认值,但它始终具有我提交的最后一个答案的值。我已经看过更改子组件中的状态,但这似乎并没有做到,并且希望得到任何建议/想法?代码如下:
// 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>;
}
}
这是我第一次发布关于堆栈溢出的问题,所以如果我遗漏了任何细节,请告诉我。
谢谢!
答案 0 :(得分:0)
我能够通过向 TextField 元素添加一个 key 属性来回答这个问题,并确保每个问题都会改变它。在这种情况下的答案。这不是最佳,因为它错过了具有相同答案的两个问题的用例(这不会触发重新渲染)。更好的方法可能是传递一个计数器或其他东西。它也可能不是最干净的解决方案,因此在此期间仍然欢迎更好的解决方案。