首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在React中访问子对象的状态

如何在React中访问子对象的状态
EN

Stack Overflow用户
提问于 2015-01-10 00:28:21
回答 3查看 238.3K关注 0票数 275

我有以下结构:

FormEditor -保存FieldEditor FieldEditor的多个实例-编辑表单的字段,并在其状态下保存有关该字段的各种值

当在FormEditor中单击一个按钮时,我希望能够从所有FieldEditor组件收集有关字段的信息、处于其状态的信息,并将其全部放在FormEditor中。

我考虑将关于字段的信息存储在FieldEditor的状态之外,并将其置于FormEditor的状态中,然而,这将需要FormEditor在每个FieldEditor组件发生变化时监听它们,并将它们的信息存储在其状态中。

我不能直接访问孩子的状态吗?它是理想的吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-01-10 18:11:17

如果您已经有了单个FieldEditors的onChange处理程序,我不明白为什么您不能将状态向上移动到FormEditor组件,然后从那里向下传递一个将更新父状态的FieldEditors回调。对我来说,这似乎是一种更具反应性的方式。

大概是这样的:

代码语言:javascript
复制
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} />;
};

原始-预钩版本:

代码语言:javascript
复制
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);

票数 174
EN

Stack Overflow用户

发布于 2015-03-27 22:39:07

在我详细介绍如何访问子组件的状态之前,请务必阅读Markus-ipse关于处理此特定场景的更好解决方案的答案。

如果您确实希望访问组件的子项的状态,则可以为每个子项分配一个名为ref的属性。现在有两种方法来实现引用:使用React.createRef()和回调引用。

使用React.createRef()

从React 16.3开始,这是目前推荐的使用引用的方式(有关更多信息,请参阅the documentation )。如果您使用的是较早的版本,请参阅下面有关回调引用的内容。

您需要在父组件的构造函数中创建一个新的引用,然后通过ref属性将其分配给子组件。

代码语言:javascript
复制
class FormEditor extends React.Component {
  constructor(props) {
    super(props);
    this.FieldEditor1 = React.createRef();
  }
  render() {
    return <FieldEditor ref={this.FieldEditor1} />;
  }
}

为了访问这种ref,您需要使用:

代码语言:javascript
复制
const currentFieldEditor1 = this.FieldEditor1.current;

这将返回已挂载组件的一个实例,这样您就可以使用currentFieldEditor1.state访问该状态。

简单地说,如果您在DOM节点而不是组件(例如<div ref={this.divRef} />)上使用这些引用,那么this.divRef.current将返回底层DOM元素而不是组件实例。

回调引用

此属性接受一个回调函数,该函数被传递一个对附加组件的引用。此回调在组件挂载或卸载后立即执行。

例如:

代码语言:javascript
复制
<FieldEditor
    ref={(fieldEditor1) => {this.fieldEditor1 = fieldEditor1;}
    {...props}
/>

在这些示例中,引用存储在父组件上。要在代码中调用此组件,可以使用:

代码语言:javascript
复制
this.fieldEditor1

然后使用this.fieldEditor1.state获取状态。

需要注意的一件事是,在尝试访问^_^之前,请确保子组件已经呈现

如上所述,如果您在DOM节点而不是组件(例如<div ref={(divRef) => {this.myDiv = divRef;}} />)上使用这些引用,那么this.divRef将返回底层DOM元素而不是组件实例。

更多信息

如果你想了解有关React的ref属性的更多信息,请查看Facebook上的this page

确保你阅读了"Don't Overuse Refs“一节,其中说你不应该使用孩子的state来”让事情发生“。

票数 210
EN

Stack Overflow用户

发布于 2021-12-22 02:01:14

您可以通过向子组件传递回调来访问子状态。

代码语言:javascript
复制
const Parent = () => {
  return (
    <Child onSubmit={(arg) => { 
             console.log('accessing child state from parent callback: ', arg) 
           }} 
    /> 
  )
}

const Child = ({onSubmit}) => {
    const [text, setText] = useState('');

    return (
      <>
        <input value={text} onChange={setText}>
        <button onClick={() => onSubmit(search)} />
      </>
    )
}

现在,如果单击子组件中的按钮,您将执行从父组件传递的函数,并可以访问子组件的状态变量。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27864951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档