我有一个包含几层子组件的表单。表单的状态保持在最高级别,而我向下传递了作为更新最高级别的道具的函数。唯一的问题是,当表单变得很大(您可以动态添加问题)时,每个单个组件都会在其中一个更新时重新加载。这是我的代码的简化版本(或codesandbox:https : //codesandbox.io/s/636xwz3rr ):const App = () => { return <Form />;}const initialForm = { id: 1, sections: [ { ordinal: 1, name: "Section Number One", questions: [ { ordinal: 1, text: "Who?", response: "" }, { ordinal: 2, text: "What?", response: "" }, { ordinal: 3, text: "Where?", response: "" } ] }, { ordinal: 2, name: "Numero dos", questions: [ { ordinal: 1, text: "Who?", response: "" }, { ordinal: 2, text: "What?", response: "" }, { ordinal: 3, text: "Where?", response: "" } ] } ]};const Form = () => { const [form, setForm] = useState(initialForm); const updateSection = (idx, value) => { const { sections } = form; sections[idx] = value; setForm({ ...form, sections }); }; return ( <> {form.sections.map((section, idx) => ( <Section key={section.ordinal} section={section} updateSection={value => updateSection(idx, value)} /> ))} </> );};const Section = props => { const { section, updateSection } = props; const updateQuestion = (idx, value) => { const { questions } = section; questions[idx] = value; updateSection({ ...section, questions }); }; console.log(`Rendered section "${section.name}"`); return ( <> <div style={{ fontSize: 18, fontWeight: "bold", margin: "24px 0" }}> Section name: <input type="text" value={section.name} onChange={e => updateSection({ ...section, name: e.target.value })} /> /> ))} </div> </> );};我已经尝试过使用useMemo和useCallback,但是我不知道如何使它工作。问题是传递函数以更新其父级。我无法弄清楚如何在每次表单更新时不对其进行更新。我无法在任何地方在线找到解决方案。也许我在寻找错误的东西。感谢您提供的任何帮助!
3 回答

慕桂英4014372
TA贡献1871条经验 获得超13个赞
通过使用复杂的表单解决此问题,我实现的技巧是onBlur={updateFormState}
通过组件的prop传递给组件的输入元素上触发将表单数据从组件提升到父表单。
为了更新组件的输入要素,我onChange={handleInput}
使用了组件内部的状态,然后当输入(或组件作为一个整体,如果组件中有多个输入字段)失去焦点时,通过提升功能将组件状态传递给组件。
这有点hacky,并且由于某种原因可能是错误的,但是它在我的机器上可以工作。;-)
添加回答
举报
0/150
提交
取消