2017-05-13 35 views
1

Reactには3つのコンポーネントがあり、1つはフォームにレンダリングするために私の子コンポーネントを渡すコンテナとして機能します。フォームが送信されると、親コンポーネント内の各子コンポーネントを取得し、それぞれのコンポーネントをループし、私のサーバが期待するオブジェクトを作成し、オブジェクトのリストをサーバに送り返したいと思います。私は、親コンポーネントのonSubmit関数内の子コンポーネントにアクセスするのに苦労しています。ここで Reactで子供から親にデータを渡す

は私の親コンポーネント

ParentFixturesComponent.js私の親は、すべて私の子供たちのコンポーネント

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; 

をレンダリング私のフォームを保持している

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; 

コンポーネントでありますそして最後に私の子供の個人的なフォーム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

react render()の要素のキーを生成するのに 'uuid()'を使わないでください。 render()が実行されるたびに新しいキーが作成され、必要以上に多くのdom操作が発生します。レンダリングでキーの一貫性を維持します。この場合は、 'i'を使用します。 –

3

は、あなたが小道具や状態の違いについて尋ねています。

コンポーネントを制御するデータには、propsstateの2種類があります。 propsは親によって設定され、コンポーネントの存続期間を通じて固定されます。変更されるデータについては、stateを使用する必要があります。Docs

これはスマート/ダム(またはロジック/ディスプレイまたはコンテナ/プレゼンター)コンポーネントにも対処します。

あなたの親コンポーネントは、すべての状態とそれを変更するためのロジックを保持し、次にすべてを下位コンポーネントとして他のコンポーネントに渡す必要があります。あなたの子コンポーネントは実際には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} 
     /> 
    ) 
    } 

} 
関連する問題