本文介绍如何让父组件(如 `createquiz`)在点击“add question”按钮前,准确获知所有已渲染的子组件(如 `questionform`)是否已完成必填字段填写,从而实现受控的表单动态添加。
要实现在点击“Add Question”前校验所有已存在题目的完整性,关键在于将子组件的表单状态“上提”并集中管理,而非让每个
以下是重构后的完整实现思路:
每个题目应是一个包含所有字段的对象(而非仅 { value: true, id }),例如:
{
id: 'xyz123',
question: '',
answerOne: '',
answerTwo: '',
answerThree: '',
answerFour: '',
correctAnswer: ''
}更新 CreateQuiz 的初始状态与 addQuestion:
function CreateQuiz() {
const [questionsArray, setQuestionsArray] = useState([
{
id: nanoid(),
question: '',
answerOne: '',
answerTwo: '',
answerThree: '',
answerFour: '',
correctAnswer: ''
}
]);
const addQuestion = () => {
// ✅ 校验:确保所有已有题目字段非空
const allFilled = questionsArray.every(q =>
q.question.trim() &&
q.answerOne.trim() &&
q.answerTwo.trim() &&
q.answerThree.trim() &&
q.answerFour.trim() &&
q.correctAnswer.trim()
);
if (!allFilled) {
alert('请先完成当前所有题目的所有必填项!');
return;
}
// ✅ 添加新题目(带默认空值)
setQuestionsArray(prev => [
...prev,
{
id: nanoid(),
question: '',
answerOne: '',
answerTwo: '',
answerThree: '',
answerFour: '',
correctAnswer: ''
}
]);
};
return (
Quiz Creator
{questionsArray.map((question) => (
{
setQuestionsArray(prev =>
prev.map(q => (q.id === question.id ? updatedQuestion : q)
);
}}
/>
))}
);
} function QuestionForm({ question, onChange }) {
const handleChange = (field, value) => {
onChange({
...question,
[field]: value
});
};
return (
handleChange('question', e.target.value)}
/>
handleChange('answerOne', e.target.value)}
/>
handleChange('answerTwo', e.target.value)}
/>
handleChange('answerThree', e.target.value)}
/>
handleChange('answerFour', e.target.value)}
/>
handleChange('correctAnswer', e.target.value)}
/>
);
}这种“状态提升 + 受控组件 + 显式校验”的组合,是 React 中处理跨层级表单协同的经典且优雅解法。