2016-05-31 95 views
4

背景传递值从阵营无国籍儿童家长

我试图从一个阵营无国籍子组件(AddConditionSelect)到母部件(AddConditionDashboard)通过输入值字段(conditionTitle),将保持我的状态。

问题

我跟着React documentation所示的模型,但他们使用的是裁判,这只有在组件是有状态的作品。我不想在子组件中设置任何状态,但仍然能够访问父项中的输入。

在目前的形式中,我得到一个警告,无状态函数组件不能被给予引用,导致道具为空和未定义。

父组件:

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; 
+1

您能不能告诉我们您的输入组件?这将有所帮助。 – QoP

+0

输入组件只是一个Rebass组件 - http://jxnblk.com/rebass/#Input – Dan

回答

5

如何直接传递的事件处理程序<Input>?您可以直接通过关于变更事件到父这样(的<Input>祖父母),你可以提取event.target.value的值,因此没有必要使用裁判:

注:可能必须bindonUserInputChange()在上下文你父类的构造,因为事件处理程序对事件发生的时间作为他们的背景下默认元素:

家长

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> 
    ); 
    } 
} 
+0

谢谢你的超级详细的答案!现在更清楚了。然而,具有输入的子组件现在可以正确渲染(没有错误),但我无法填充输入字段(尽管在控制台中没有错误)。我想这与双向绑定有关,在以前的版本的孩子组件... – Dan

+1

@丹无需担心,高兴地帮助:)。顺便说一句,你究竟意味着什么“我无法填充输入字段”? – nem035

+0

谢谢:)在输入字段中键入不起作用。在注释掉设置状态'this.state = {conditionTitle:''}'的构造函数部分后,可以填充输入字段。但是,'onUserInputChange()'中的console.logging没有任何作用 - 所以它就像它的函数不会触发输入更改。 :S – Dan

0
  1. 你并不需要裁判。值可以从事件中提取。因此,你的孩子组件变得更简单。
  2. 您可以使用value link pattern进一步简化您的代码。

    类AddConditionDashboard延伸React.Component { 构造(道具){ 超级(道具);

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

    }

    渲染(){ 常量{错误,segmentId} =此。道具;

    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;