最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Passing Values via Props From React Stateless Child to Parent - Stack Overflow

programmeradmin5浏览0评论

CONTEXT

I'm trying to pass input value fields (conditionTitle) from a React Stateless child ponent (AddConditionSelect) to the parent ponent (AddConditionDashboard) that will hold my state.

PROBLEM

I followed the model shown in the React documentation, but they are using refs, which only works if the ponent is stateful. I do not want to have to set any state in the child ponent, but still be able to access the input in the parent.

In its current form, I am getting a Warning, that the stateless function ponents cannot be given refs, resulting in props being null and undefined.

Parent Component:

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;

Child ponent:

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;

CONTEXT

I'm trying to pass input value fields (conditionTitle) from a React Stateless child ponent (AddConditionSelect) to the parent ponent (AddConditionDashboard) that will hold my state.

PROBLEM

I followed the model shown in the React documentation, but they are using refs, which only works if the ponent is stateful. I do not want to have to set any state in the child ponent, but still be able to access the input in the parent.

In its current form, I am getting a Warning, that the stateless function ponents cannot be given refs, resulting in props being null and undefined.

Parent Component:

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;

Child ponent:

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;
Share Improve this question asked May 31, 2016 at 20:00 DanDan 5891 gold badge6 silver badges20 bronze badges 2
  • 1 can you show us your Input ponent? That would help. – QoP Commented May 31, 2016 at 20:09
  • The input ponent is just a Rebass ponent - jxnblk./rebass/#Input – Dan Commented May 31, 2016 at 20:12
Add a ment  | 

2 Answers 2

Reset to default 6

How about passing the event handler directly to <Input>? This way you pass the on change event directly to your parent (grandparent of <Input>) and you can extract the value from event.target.value so no need to use refs:

Note: You might have to bind the context of onUserInputChange() in you parent's constructor because event handlers have the element on which the event happened as their context by default:

Parent

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>
    />

    // ...
  }
  // ...

Child:

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. You don't need ref. value can be extracted from the event. Thus, you children ponent bees simpler.
  2. You can simplify your code further using the value link pattern.

    class AddConditionDashboard extends 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;

And child ponent

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;
发布评论

评论列表(0)

  1. 暂无评论