2017-05-13 3 views
1

Ich habe 3 Komponenten in React, einer fungiert als ein Container, der meine untergeordneten Komponenten weitergibt, um in einem Formular gerendert zu werden. Wenn das Formular gesendet wird, möchte ich jede der untergeordneten Komponenten in meiner übergeordneten Komponente abrufen, durch jede einzelne Schleife führen, ein Objekt erstellen, das mein Server erwartet, und dann die Liste der Objekte an den Server zurücksenden. Ich habe Schwierigkeiten, auf die untergeordneten Komponenten in meiner onSubmit-Funktion in meiner übergeordneten Komponente zuzugreifen.Übergeben Sie Daten von Kind zu Eltern in React

Hier ist meine Mutterkomponente

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; 

Komponente, die meine Form hält, wo meine Eltern alle meine Kinder Komponenten

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; 

rendert Und schließlich mein Kind individuelle Form c Komponente. mit props

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

Hallo Nick, du solltest Funktionen als Requisiten von Eltern zu Kind weitergeben, die als Callbacks fungieren. Wenn also die Funktion onSubmit() aufgerufen wird, haben Sie alle Daten in Ihrem übergeordneten Komponentenstatus. Für Beispielcode beziehen sich auf diesen Faden http://stackoverflow.com/questions/38394015/how-to-pass-data-from-child-component-to-its-parent-in-reactjs –

Antwort

4

eine Funktion in Ihrer Mutter definieren und es das Kind, rufen Sie die übergeordnete Funktion in geordnete Komponente senden. Etwas wie:

Eltern

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; 

Kind

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

Dieses funktionierte für mich, aber ich musste zuerst die Funktion 'childFunctionHere' im Child-Konstruktor binden. – x7iBiT

+0

Verwenden Sie nicht 'uuid()', um Schlüssel für Elemente in react render() zu generieren. Dadurch werden jedes Mal, wenn render() ausgeführt wird, neue Schlüssel erstellt, die viel mehr Dom-Manipulation als nötig verursachen. Keep Keys konsistent über Render, in diesem Fall mit "i". –

3

Im Wesentlichen Sie fragen, über den Unterschied zwischen Requisiten und Staat.

Es gibt zwei Arten von Daten, die eine Komponente zu steuern: props und state. props werden vom übergeordneten Element festgelegt und während der gesamten Lebensdauer einer Komponente festgelegt. Für Daten, die sich ändern werden, müssen wir state verwenden.Docs

Dies betrifft auch Smart/Dumme (oder Logik/Display oder Container/Presenter) Komponenten.

Ihre Elternkomponente sollte den gesamten Status und die Logik zum Ändern enthalten und dann alles als Requisiten an die anderen Komponenten übergeben. Ihre Kind-Komponenten sollten nicht wirklich eine state haben, sie behandeln nur die Anzeige und, wenn etwas passiert, senden sie einfach diesen Anruf zurück an die Eltern-Komponente, um zu tun, was zu tun ist.

Wenn die untergeordneten Komponenten diese Handler über Requisiten aufrufen, werden sie im übergeordneten Objekt ausgeführt und aktualisieren den Status dort. Dann können Sie einfach den Status im Eltern sammeln und übermitteln.

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} 
     /> 
    ) 
    } 

} 
Verwandte Themen