2016-05-31 81 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;