【问题标题】:Passing Values via Props From React Stateless Child to Parent通过 Props 从 React 无状态子级向父级传递值
【发布时间】:2016-09-29 23:52:39
【问题描述】:

上下文

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

问题

我遵循React documentation 中显示的模型,但他们使用的是 refs,这仅在组件是有状态的情况下才有效。我不想在子组件中设置任何状态,但仍然能够访问父组件中的输入。

在当前的形式中,我收到了一个警告,即无法为无状态函数组件提供 refs,从而导致 props 为 null 且未定义。

父组件:

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;

【问题讨论】:

  • 您能向我们展示您的输入组件吗?这会有所帮助。
  • 输入组件只是一个 Rebass 组件 - jxnblk.com/rebass/#Input

标签: javascript reactjs ecmascript-6


【解决方案1】:

将事件处理程序直接传递给&lt;Input&gt; 怎么样?这样,您可以将 on change 事件直接传递给您的父级(&lt;Input&gt; 的祖父级),您可以从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>
    );
  }
}

【讨论】:

  • 感谢您的超级详细解答!现在清楚多了。但是,带有输入的子组件现在已正确呈现(没有错误),但我无法填充输入字段(虽然控制台中没有错误)。我想这与我的双向绑定有关是在以前版本的子组件中做的...
  • @Dan 不用担心,很高兴为您提供帮助 :)。顺便说一句,“我无法填充输入字段”到底是什么意思?
  • 谢谢 :) 在输入字段中输入无效。在注释掉我的构造函数中设置状态this.state = { conditionTitle: '' } 的部分之后,可以填充输入字段。但是,onUserInputChange() 中的 console.logging 没有任何效果 - 所以就像输入更改时函数不会触发一样。 :S
  • 尝试使用浏览器调试器在onUserInputChange 中放置一个断点并确保它被调用。如果不是,请确保子函数中的 this.props.onUserInputChange 指向父函数。如果是这样,请确保 &lt;Input&gt; 中的 onChange 实际被调用。如果您收到调用但值未更新,请确保 onChange 实际上将值传递回方法,并且使用更新的 this.props.conditionTitle 调用子级的 render 方法。只需确保从顶部组件正确链接到 &lt;Input&gt; :)
  • 干杯!调试跟踪有帮助!我忘记在输入元素 onChange 上调用道具。再次感谢:)
【解决方案2】:
  1. 您不需要参考。可以从事件中提取值。因此,您的子组件变得更简单。
  2. 您可以使用value link pattern 进一步简化您的代码。

    类 AddConditionDashboard 扩展 React.Component { 构造函数(道具){ 超级(道具);

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

    }

    渲染(){ 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>
    );
    

    }

    }

    导出默认的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;

【讨论】:

    猜你喜欢
    • 2020-09-09
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多