2017-05-13 83 views
1

我在React中有3個組件,其中一個作爲一個容器傳遞我的孩子組件以在表單中呈現。當提交表單時,我希望獲取父組件中的每個子組件,循環遍歷每個組件,創建一個對象,然後將對象列表發送回服務器。我努力在我的父組件的onSubmit函數中訪問子組件。將數據從孩子傳遞給父母React

這裏是我的父組件

ParentFixturesComponent.js

class ParentFixturesComponent extends Component { 

    constructor() { 
     super(); 
     this.state = { 
      numChildren: 0, 
     }; 
    } 

    onAddMatch() { 
     this.setState({ 
      numChildren: this.state.numChildren + 1 
     }); 
    } 

    onSubmit(e) { 
     e.preventDefault(); 
     // loop through the child components 
     // create a match object with them 
     // var match = { 
     //  id: uuid(), 
     //  title: uuid(), 
     //  start: e.something, 
     //  end: e.something, 
     // }; 
     console.log("submit works"); 
    } 

    render() { 
     const children = []; 
     for (let i = 0; i < this.state.numChildren; i += 1) { 
      children.push(<SingleMatchForm key={uuid()}/>) 
     } 

     return (
      <Fixtures addMatch={this.onAddMatch.bind(this)} save={this.onSubmit.bind(this)} > 
       {children} 
      </Fixtures> 
     ); 
    } 

} 

export default ParentFixturesComponent; 

組件保持自己的狀態在我的父母都呈現我的孩子們組成部分

ChildFixturesContainer.js

class Fixtures extends Component { 


    constructor(props) { 
     super(props); 
     this.handleChange = this.handleChange.bind(this); 
    } 

    handleChange(name) { 
     this.console.log(this.props); 
    } 

    render() { 
     return (
      <div className="tray tray-center"> 
       <div className="row"> 
        <div className="col-md-8"> 
         <div className="panel mb25 mt5"> 
          <div className="panel-heading"> 
           <span className="panel-title">Fixtures</span> 
          </div> 
          <div className="panel-body p20 pb10"> 
           <div id="fixture-parent" onChange={this.handleChange.bind(this)}> 
            {this.props.children} 
           </div> 
          </div> 
          <div className="section-divider mb40" id="spy1"> </div> 
          <button className="btn btn-primary tm-tag" onClick={this.props.addMatch}>Add Match</button> 
          <button className="btn btn-alert tm-tag" onClick={this.props.save}>Save</button> 
         </div> 
        </div> 
       </div> 
      </div> 
     ); 
    } 

} 

export default Fixtures; 

最後我的孩子個人形式c omponent。

SingleMatchComponent.js

class SingleMatchForm extends Component { 

    constructor() { 
     super(); 
     this.state = { 
      startDate: moment() 
     }; 
    } 

    handleChange(date) { 
     this.setState({ 
      startDate: date 
     }); 
    } 

    render() { 
     return (
      <div className="row"> 
       <div key={this.props.id} className="form-group"> 
        <label className="control-label col-md-2">New Match</label> 
        <div className="col-md-6"> 
         <DatePicker 
          selected={this.state.startDate} 
          onChange={this.handleChange.bind(this)}/> 
         <div className="section-divider mb40" id="spy1"> </div> 
        </div> 
       </div> 
      </div> 
     ); 
    } 

} 

export default SingleMatchForm; 
+0

嗨,尼克,你應該傳遞函數作爲從父母到孩子,作爲回調作爲道具。因此,當調用onSubmit()函數時,您的父組件狀態中將包含所有數據。對於示例代碼請參閱此線程http://stackoverflow.com/questions/38394015/how-to-pass-data-from-child-component-to-its-parent-in-reactjs –

回答

4

在父定義一個函數,並將其發送給孩子,叫使用props在子組件父功能。喜歡的東西:

家長

class ParentFixturesComponent extends Component { 

    // don't forget to bind the function in parent 
    constructor() { 
     super(); 
     this.state = { 
      numChildren: 0, 
     }; 
     this.someFunctionHere = this.someFunctionHere.bind(this); 
    } 

    someFunctionHere(param) { 
     // do whatever you need 
    } 

    render() { 
     const children = []; 
     for (let i = 0; i < this.state.numChildren; i += 1) { 
      children.push(<SingleMatchForm key={uuid()}/>) 
     } 

     return (
      <Fixtures 
       addMatch={this.onAddMatch.bind(this)} 
       save={this.onSubmit.bind(this)} 
       someFunctionHere={this.someFunctionHere} 
      > 
       {children} 
      </Fixtures> 
     ); 
    } 
} 

export default ParentFixturesComponent; 

兒童

class Fixtures extends Component { 

    // constructor and other stuff... 

    childFunctionHere() { 
     this.props.someFunctionHere(params);    
    } 

    render() { 
     return (
      <div id="fixture-parent" onChange={this.childFunctionHere}> 
     ); 
    } 
} 

export default Fixtures; 
+0

這對我工作,但我必須先在子構造函數中綁定'childFunctionHere'函數。 – x7iBiT

+0

請勿使用'uuid()'爲反應render()中的元素生成鍵。這會在render()每次運行時創建新的鍵,並導致更多的dom操作。保持鍵在整個渲染過程中保持一致,在本例中使用'i'。 –

3

從本質上講,你問的道具和狀態之間的差異。

有兩種類型的數據控制組件:propsstateprops由父級設置,它們在組件的整個生命週期中都是固定的。對於將要改變的數據,我們必須使用stateDocs

這也解決智能/愚蠢(或邏輯/顯示或容器/演示者)組件。

你的父組件應該保存所有的狀態和改變它的邏輯,然後把所有東西都傳遞給其他組件作爲道具。你的孩子組件甚至不應該有一個state他們只是處理顯示它,並且,當發生什麼事情時,他們只是將該呼叫發送回父組件以完成任何需要完成的事情。

當子組件通過道具調用這些處理程序時,它們將在父項中執行,更新那裏的狀態。然後你可以收集父母的狀態並提交。

class TheParent extends component { 

    constructor() { 
    super(); 
    this.state = { 
     someState: 0, 
     someMoreState: 1, 
     evenMoreState: 2 
    }; 
    autoBind(this) // <- use autobind so you don't have to list them all out 
    } 

    updateSomeState() { 
     // do something 
    } 

    updateSomeMoreState() { 
     // do something 
    } 

    updateEvenMoreState() { 
     // do something 
    } 

    onSubmit() { 
    // get state and submit 
    } 

    render() { 
    return (
     <Component1 
     someProp={this.state.someState} 
     handler={this.updateSomeState} 
     /> 
     <Component2 
     someProp={this.state.someMoreState} 
     handler={this.updateSomeMoreState} 
     />   
     <Component2 
     someProp={this.state.evenMoreState} 
     handler={this.updateEvenMoreState} 
     /> 
    ) 
    } 

} 
相關問題