现在是2020年了,很多人会来这里寻找类似的解决方案,但使用hook(它们很棒!)以及在代码清洁度和语法方面的最新方法。
因此,正如前面的回答所述,解决这类问题的最佳方法是将状态保存在子组件fieldEditor之外。你可以用多种方法来做。
最“复杂”的是父节点和子节点都可以访问和修改的全局上下文(状态)。当组件位于树层次结构的非常深处时,这是一个很好的解决方案,因此在每个关卡中发送道具的成本很高。
在这种情况下,我认为这是不值得的,一种更简单的方法将为我们带来我们想要的结果,只需使用强大的React.useState()。
使用React.useState()钩子的方法比使用Class组件简单得多
如前所述,我们将处理更改,并将子组件fieldEditor的数据存储在父组件fieldForm中。要做到这一点,我们将发送一个引用函数,该函数将处理并应用对fieldForm状态的更改,你可以这样做:
function FieldForm({ fields }) {
const [fieldsValues, setFieldsValues] = React.useState({});
const handleChange = (event, fieldId) => {
let newFields = { ...fieldsValues };
newFields[fieldId] = event.target.value;
setFieldsValues(newFields);
};
return (
<div>
{fields.map(field => (
<FieldEditor
key={field}
id={field}
handleChange={handleChange}
value={fieldsValues[field]}
/>
))}
<div>{JSON.stringify(fieldsValues)}</div>
</div>
);
}
请注意,React.useState({})将返回一个数组,其中位置0是调用时指定的值(在本例中为空对象),位置1是对函数的引用
这将修改值。
现在,对于子组件FieldEditor,您甚至不需要创建带有return语句的函数。一个带有箭头函数的精简常数就可以了!
const FieldEditor = ({ id, value, handleChange }) => (
<div className="field-editor">
<input onChange={event => handleChange(event, id)} value={value} />
</div>
);
我们做完了,没有别的了。有了这两个简单的功能组件,我们的最终目标就是“访问”子组件的FieldEditor值,并在父组件中显示它。
你可以看看5年前的答案,看看Hooks是如何让React代码变得更精简的(精简了很多!)
希望我的回答能帮助您学习和理解更多关于Hooks的知识,如果您想查看一个工作示例,请点击这里。