我有以下结构:
FormEditor- 拥有 FieldEditor 的多个实例 FieldEditor- 编辑表单的字段并在其状态下保存有关它的各种值
FormEditor
FieldEditor
当在 FormEditor 中单击按钮时,我希望能够从所有FieldEditor组件中收集有关字段的信息、处于其状态的信息,并将其全部包含在 FormEditor 中。
我考虑将有关字段的信息存储在FieldEditor‘ 状态之外,并将其置于FormEditor‘ 状态。但是,这将需要在其每个组件更改FormEditor时监听其每个FieldEditor组件并将其信息存储在其状态中。
我不能只访问孩子的状态吗?理想吗?
如果您已经为各个 FieldEditor 提供了 onChange 处理程序,我不明白为什么您不能将状态向上移动到 FormEditor 组件,然后将回调从那里传递给将更新父状态的 FieldEditor。对我来说,这似乎是一种更 React-y 的方式。
可能是这样的:
const FieldEditor = ({ value, onChange, id }) => { const handleChange = event => { const text = event.target.value; onChange(id, text); }; return ( <div className="field-editor"> <input onChange={handleChange} value={value} /> </div> ); }; const FormEditor = props => { const [values, setValues] = useState({}); const handleFieldChange = (fieldId, value) => { setValues({ ...values, [fieldId]: value }); }; const fields = props.fields.map(field => ( <FieldEditor key={field} id={field} onChange={handleFieldChange} value={values[field]} /> )); return ( <div> {fields} <pre>{JSON.stringify(values, null, 2)}</pre> </div> ); }; // To add the ability to dynamically add/remove fields, keep the list in state const App = () => { const fields = ["field1", "field2", "anotherField"]; return <FormEditor fields={fields} />; };
原始 - 挂钩前版本:
class FieldEditor extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange(event) { const text = event.target.value; this.props.onChange(this.props.id, text); } render() { return ( <div className="field-editor"> <input onChange={this.handleChange} value={this.props.value} /> </div> ); } } class FormEditor extends React.Component { constructor(props) { super(props); this.state = {}; this.handleFieldChange = this.handleFieldChange.bind(this); } handleFieldChange(fieldId, value) { this.setState({ [fieldId]: value }); } render() { const fields = this.props.fields.map(field => ( <FieldEditor key={field} id={field} onChange={this.handleFieldChange} value={this.state[field]} /> )); return ( <div> {fields} <div>{JSON.stringify(this.state)}</div> </div> ); } } // Convert to a class component and add the ability to dynamically add/remove fields by having it in state const App = () => { const fields = ["field1", "field2", "anotherField"]; return <FormEditor fields={fields} />; }; ReactDOM.render(<App />, document.body);