【问题标题】:Access state of parent component in a child component?在子组件中访问父组件的状态?
【发布时间】:2018-07-17 15:32:36
【问题描述】:

我是 react js 新手,我需要获取组件的状态以供另一个类访问,我遇到了这个问题,因为我使用的是原子设计,因为在一个组件中编写所有内容正在变成一个问题,这是我的代码: 头部组件

class Headcomponent extends React.Component{

  constructor (props) {

    super(props);
    this.state = {
      email: '',
      password: '',
      formErrors: {email: '', password: ''},
      emailValid: false,
      passwordValid: false,
      formValid: false,
      items: [],

    }
  }


    this.setState({formErrors: fieldValidationErrors,
                    emailValid: emailValid,
                    passwordValid: passwordValid
                  }, this.validateForm);
}

validateForm() {
  this.setState({formValid: this.state.emailValid && 
  this.state.passwordValid});
}


render(){
        return (
  <Form fields={this.props.form} buttonText="Submit" />
        );
    }
}


Headcomponent.propTypes = {
  form: PropTypes.array,
};

Headcomponent.defaultProps = {
  form: [
    {
      label: 'label1',
      placeholder: 'Input 1',
    },
    {
      label: 'label2',
      placeholder: 'Placeholder for Input 2',
    },
  ],
};

export default Headcomponent;

form.js

   const Form = props => (
      <form className="Form">
        {
          props.fields.map((field, i) => (<LabeledInput label={field.label} placeholder={field.placeholder} key={i}/>))
        }
        <Button text={props.buttonText} />
      </form>
    );

    Form.propTypes = {
      fields: PropTypes.arrayOf(PropTypes.object).isRequired,
      buttonText: PropTypes.string.isRequired,
    };

    export default Form;

LabeledInput.js(我需要传递我的密码状态)

const LabeledInput = props => (
  <div className={`form-group `} >
    <Label text={props.label} />
    <Input value={props.value} placeholder={props.placeholder} type="text" onChange={props.onChange} />
    <div class="valid-feedback">{props.errorMessage}</div>
    <small class="form-text text-muted">{props.exampleText}</small>
  </div>
);

LabeledInput.propTypes = {
  label: PropTypes.string.isRequired,
  placeholder: PropTypes.string,
  onChange: PropTypes.func.required,
  value: PropTypes.string.isRequired,
  exampleText: PropTypes.string,
  errorMessage: PropTypes.string,
};

export default LabeledInput;

如何在LabeledInput 中访问headComponent 的状态?

【问题讨论】:

  • 将headComponent的状态作为prop传递给form组件,然后传递给labelledcomponent。如果组件完全不相关,则需要使用 redux 来管理状态。
  • 如果我的回复回答了您的问题,请接受答案。如果您仍然遇到问题,请告诉我们

标签: javascript reactjs ecmascript-6 state react-props


【解决方案1】:

最合理的方式是把它(你需要的Headcomponent的状态的值)作为道具传递:

Headcomponent.js

class Headcomponent extends React.Component {
  constructor (props) {
    super(props);

    this.state = {
      email: '',
      password: '',
      formErrors: {email: '', password: ''},
      emailValid: false,
      passwordValid: false,
      formValid: false,
      items: [],
    }
  }

  render() {
    return (
      <Form
        fields={this.props.form}
        formValid={this.state.formValid}  // from Headcomponent's state
        buttonText="Submit"
      />
    );
  }
}

Form.js

const Form = props => (
   <form className="Form">
     {
       props.fields.map((field, i) => (
         <LabeledInput
           label={field.label}
           formValid={props.formValid}  // from Headcomponent's state
           placeholder={field.placeholder}
           key={i}
         />
       ))
     }
     <Button text={props.buttonText} />
   </form>
 );

LabeledInput.js

 const LabeledInput = props => (
   <div className={`form-group `} >
     { props.formValid && 'This form is valid' }  // from Headcomponent's state
     <Label text={props.label} />
     <Input value={props.value} placeholder={props.placeholder} type="text" onChange={props.onChange} />
     <div class="valid-feedback">{props.errorMessage}</div>
     <small class="form-text text-muted">{props.exampleText}</small>
   </div>
 );

因此,如果 Headcomponent 的状态随时更新,它将传播到 LabeledInput 组件

【讨论】:

    【解决方案2】:

    LabeledInput 中访问headComponent 的状态以保持向下传递的最简单方法。

    如果你想从headComponent 中的LabeledInput 访问值this.state.password,那么你将这个this.state.password 作为prop 传递给render 方法中的表单组件

       render(){
            return (
              <Form 
                fields={this.props.form} 
                buttonText="Submit" 
                password={this.state.password} />
            );
        }
    

    这使您可以访问 this.state.password 作为 Form 组件内的道具。然后重复该过程并将其传递给表单内的LabeledInput 组件

    const Form = props => (
          <form className="Form">
            {
              props.fields.map((field, i) => (
                <LabeledInput 
                    label={field.label} 
                    placeholder={field.placeholder} 
                    key={i}
                    password={this.props.password}
                 />))
            }
            <Button text={props.buttonText} />
          </form>
        );
    

    然后,您可以通过调用this.props.password 访问LabeledInput 组件内的值。

    【讨论】:

    • 实际上还有另一个问题,它与这个问题有关,所以我真的不想为它打开另一个问题,如果我想在标签中传递一个动作到我的输入,我是否也这样做输入?传递函数和传递数据一样吗?
    • 是的,你可以用同样的方式传递函数。不过要小心调用函数的方式。如果您只是将函数放在 onClick 中,它将在页面加载时触发 onClick={this.props.actionName} 。你通常不希望这种情况发生,所以把它放在回调中,这样它只会在你点击 onClick={() =&gt; this.props.actionName} 时触发
    【解决方案3】:

    您可以使用props 来实现此目的。

    根组件:

    <div>
      <child myState="hello"></child>
    </div>
    

    子组件:

    <div>
      <child2 myOtherProperty={this.props.myState}></child2>
    </div>
    

    Child1 组件:

    <div>{this.props.myOtherProperty}</div>
    

    您还可以将函数作为属性传递给其他组件,并让它们在需要时回调根组件,如下所示:

    <div>
      <child onChange={this.myOnChangeMethodDefinedInRootComponent.bind(this)}></child>
    </div>
    

    这样,如果不使用Redux,如果子组件内部发生了变化,您就可以“告诉”根组件

    希望对你有帮助

    【讨论】:

      【解决方案4】:

      这是您正在查看的快速原型,

      将状态从头组件作为道具传递到标签组件。 label 组件的变化会改变 head 组件的状态,并强制重新渲染所有组件。

      // Head Component
      class HeadCompoent {
        constructor() {
          this.state = {
            password: '',
            userName: '',
          }
        }
      
        handleFieldChange = (key, val) => {
          this.setState({
            [key]: val,
          });
        };
      
        render() {
          <Form
            fields={[{
              item: {
                value: this.state.password,
                type: 'password',
                key: 'password'
              },
            }, {
              item: {
                value: this.state.userName,
                type: 'text',
                key: 'userName'
              }
            }]}
            handleFieldChange={this.handleFieldChange} 
          />
        }
      }
      
      // Form Component
      const Form = (fields) => (
        <div>
          {
            fields.map(p => <Label {...p} />)
          }
        </div>);
      
      
      // Label Component
      const Label = ({ type, value, key, handleFieldChange }) => {
        const handleChange = (key) => (e) => {
          handleFieldChange(key, e.target.value);
        };
      
        return (
          <input type={type} value={value} key={key} onChange={handleChange(key)} />
        );
      };
      

      【讨论】:

        【解决方案5】:

        export default headComponent 然后import 里面LabelledInout

        这是头部组件

        export default class Headcomponent extends React.Component{ 
          ...
        }
        

        标签输入组件

         import Headcomponet from './headComponent.js'
        
         const LabelledInput = (props) => {
            return(<Headcomponent />);
         }
        

        【讨论】:

        • 以及如何获取对组件正确实例的引用?
        • 您必须创建一个 this 的实例,然后创建一个访问状态的方法。不能直接引用状态,组件的创建由react处理
        • @messerbill 获取实例,你创建一个变量来存储实例。说const head = new headComponent() 然后您可以访问实例上的类方法。但是如果你只需要使用一个类而不是组件方法,你为什么要扩展 Component 类呢?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-08
        • 2019-08-03
        • 2021-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-10
        相关资源
        最近更新 更多