如何访问React中的子组件状态
如何访问React中的子组件状态
我有以下结构:
FormEditor
- 包含多个 FieldEditor
实例
FieldEditor
- 编辑表单字段并将多个值保存在其状态中
当在 FormEditor
中点击按钮时,我想从所有 FieldEditor
组件中收集关于字段的信息,这些信息在它们的状态中,并将其全部放在 FormEditor
中。
我考虑将有关字段的信息存储在 FieldEditor
状态之外,并将其放在 FormEditor
的状态中。但是,这将要求 FormEditor
监听每个 FieldEditor
组件的更改,并将它们的信息存储在其状态中。
我不能只访问子组件的状态吗?这是否是理想的方法?
如果您已经为单个FieldEditors拥有了一个onChange处理程序,我不明白为什么您不能将状态上移到FormEditor组件,然后从那里传递一个回调到FieldEditors,用于更新父状态。对我来说,这似乎更像React-y的方式。
也许类似于这样:
const FieldEditor = ({ value, onChange, id }) => { const handleChange = event => { const text = event.target.value; onChange(id, text); }; return ( ); }; const FormEditor = props => { const [values, setValues] = useState({}); const handleFieldChange = (fieldId, value) => { setValues({ ...values, [fieldId]: value }); }; const fields = props.fields.map(field => ()); return ( {fields} {JSON.stringify(values, null, 2)}); }; // To add the ability to dynamically add/remove fields, keep the list in state const App = () => { const fields = ["field1", "field2", "anotherField"]; return
; }; 原始-预挂钩版本:
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 ( ); } } 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 => ()); return ( {fields} {JSON.stringify(this.state)} ); } } // 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 ; }; ReactDOM.render( , document.body);
在详细介绍如何访问子组件状态之前,请确保阅读 Markus-ipse 关于如何处理该特定场景的更好解决方案。
如果确实希望访问组件子元素的状态,可以为每个子元素分配名为 ref
的属性。现在有两种实现引用的方法:使用 React.createRef()
和回调引用。
使用 React.createRef()
这是目前在 React 16.3 中推荐的引用方式(有关更多信息,请参见文档)。如果使用早期版本,则下面有关回调引用的内容。
您需要在父组件构造函数中创建新引用,然后通过ref
属性将其分配给子组件。
class FormEditor extends React.Component { constructor(props) { super(props); this.FieldEditor1 = React.createRef(); } render() { return; } }
为了访问这种引用,您需要使用:
const currentFieldEditor1 = this.FieldEditor1.current;
这将返回已挂载组件的实例,以便您可以使用currentFieldEditor1.state
来访问状态。
请注意,如果您在 DOM 节点上而不是组件(例如)使用这些引用,则
this.divRef.current
将返回基础 DOM 元素而不是组件实例。
回调引用
该属性使用回调函数,该函数将引用传递给所附加的组件。该回调在组件挂载或卸载后立即执行。
例如:
{this.fieldEditor1 = fieldEditor1;} {...props} />
在这些示例中,引用存储在父组件上。要在代码中调用此组件,可以使用:
this.fieldEditor1
然后使用this.fieldEditor1.state
来获取状态。
请注意,确保在尝试访问子组件之前渲染了该子组件 ^_^
与上面一样,如果您在 DOM 节点上而不是组件(例如 {this.myDiv = divRef;}} />
)使用这些引用,则this.divRef
将返回基础 DOM 元素而不是组件实例。
更多信息
如果想要了解更多关于 React 的引用属性的信息,请查看 Facebook 的 这个页面。 p>
确保阅读 "不要过度使用引用" 部分,该部分指出不应使用子级的 state
来“使事情发生”。