繁体   English   中英

通过道具将值从React Stateless Child传递给Parent

[英]Passing Values via Props From React Stateless Child to Parent

CONTEXT

我正在尝试将输入值字段( conditionTitle )从React无状态子组件( AddConditionSelect )传递到将保存我的状态的父组件( AddConditionDashboard )。

问题

我遵循React文档中显示的模型,但它们使用的是refs,只有在组件是有状态的情况下才有效。 我不想在子组件中设置任何状态,但仍然可以访问父组件中的输入。

在其当前形式中,我得到一个警告,无状态函数组件不能被赋予refs,导致props为null和undefined。

父组件:

import AddConditionSelect from '../containers/AddConditionSelect.js';

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

    this.state = {
      conditionTitle: '',
      conditionType: ''
    };
  }

  handleUserInput({conditionTitleInput}) {
    this.setState({
      conditionTitle:conditionTitle
    })

  }

  render() {
    const {error, segmentId} = this.props;

    return (
      <div>

    <AddConditionSelect segmentId={segmentId} conditionTitle={this.state.conditionTitle} onUserInput={this.handleUserInput} />


    <PanelFooter theme="default">
      <Button backgroundColor="primary" color="white" inverted={true} rounded={true} onClick={(event) => this.onSubmit(event)}>
        Next Step
      </Button>
    </PanelFooter>

      </div>
    );
  }

}

export default AddConditionDashboard;

子组件:

class AddConditionSelect extends React.Component {

  onInputChange: function() {
    this.props.onUserInput(
      this.refs.conditionTitleInput.value,
    )
  },

  render() {
    const {error} = this.props;

    return (
      <div>

        <Panel theme="info">

        <Divider />

        Please enter a name {error ? <Message inverted={true}  rounded={true}  theme="error">{error}</Message>  : null}
          <Input value={this.props.conditionTitle} ref="conditionTitleInput" label="" type="text" buttonLabel="Add Condition" name="add_segment" onChange={this.onInputChange} placeholder="Condition Title"/>

       </Panel>
     </div>
    );
  }

}
export default AddConditionSelect;

如何将事件处理程序直接传递给<Input> 这样你就可以将on change事件直接传递给你的父( <Input>祖父),你可以从event.target.value提取值,所以不需要使用refs:

注意:您可能必须在父级构造函数中bind onUserInputChange()的上下文,因为事件处理程序默认情况下将事件发生的元素作为其上下文:

class AddConditionDashboard extends React.Component {

  constructor(props) {
    // ...

    // bind the context for the user input event handler
    // so we can use `this` to reference `AddConditionDashboard`
    this.onUserInputChange = this.onUserInputChange.bind(this);
  }

  onUserInputChange({ target }) {
    const { value: conditionTitle } = target;
    this.setState({
     conditionTitle
    });
  }

  render() {
    // ...

    <AddConditionSelect segmentId={segmentId} 
                        conditionTitle={this.state.conditionTitle} 
                        onUserInputChange={this.onUserInputChange} // <-- pass event handler to child that will pass it on to <Input>
    />

    // ...
  }
  // ...

儿童:

class AddConditionSelect extends React.Component {

  render() {
    const { error } = this.props;

    return (
      <div>
        // ...

        <Input value={this.props.conditionTitle} 
               label="" 
               type="text" 
               buttonLabel="Add Condition" 
               name="add_segment" 
               onChange={this.props.onUserInputChange} // <-- Use the grandparent event handler
               placeholder="Condition Title"
        />

       // ...
     </div>
    );
  }
}
  1. 你不需要参考。 可以从事件中提取值。 因此,您的子组件变得更简单。
  2. 您可以使用值链接模式进一步简化代码。

    class AddConditionDashboard扩展了React.Component {constructor(props){super(props);

     this.state = { conditionTitle: '', conditionType: '' }; 

    }

    render(){const {error,segmentId} = this.props;

     return ( <div> <AddConditionSelect segmentId={segmentId} conditionTitle={ Link.state( this, 'conditionTitle' ) } /> <PanelFooter theme="default"> <Button backgroundColor="primary" color="white" inverted={true} rounded={true} onClick={(event) => this.onSubmit(event)}> Next Step </Button> </PanelFooter> </div> ); 

    }

    }

    export default AddConditionDashboard;

和儿童组件

const AddConditionSelect = ({ error, valueLink }) => (
    <div>

    <Panel theme="info">

    <Divider />

    Please enter a name { error ?
                            <Message inverted={true}  rounded={true}  theme="error">
                                {error}
                            </Message>  : null }
        <Input  value={ valueLink.value }
                onChange={ e => valueLink.set( e.target.value ) }
                label="" type="text"
                buttonLabel="Add Condition" name="add_segment" 
                placeholder="Condition Title"/>

    </Panel>
    </div>
);

export default AddConditionSelect;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM