子组件中父组件的访问状态?

时间:2018-02-07 11:01:48

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

我刚接触js并且我需要让另一个类访问组件的状态,我遇到了这个问题,因为我使用的是原子设计,因为在一个组件中编写所有东西都会成为一个问题,这是我的代码: 的 Headcomponent

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的状态?

5 个答案:

答案 0 :(得分:2)

最合理的方法是将它作为道具传递( 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组件

答案 1 :(得分:1)

您可以使用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

希望这会有所帮助

答案 2 :(得分:1)

以下是您正在查看的内容的快速原型,

将状态从头部组件作为道具传递到标签组件。标签组件的更改将修改头部组件的状态,并强制重新渲染所有组件。

// 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)} />
  );
};

答案 3 :(得分:1)

访问headComponentLabeledInput状态的最简单方法是继续传递它。

如果要从this.state.password内的headComponent访问值LabeledInput,则将此this.state.password作为道具传递给渲染方法中的表单组件

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

然后,您可以在Form组件中访问this.state.password作为prop。然后,您重复该过程并将其传递给表单

中的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>
    );

这样,您就可以通过调用LabeledInput来访问this.props.password组件中的值。

答案 4 :(得分:-1)

export default headComponent然后在import

LabelledInout

这是Headcomponent

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

LabelledInput组件

 import Headcomponet from './headComponent.js'

 const LabelledInput = (props) => {
    return(<Headcomponent />);
 }