2016-06-02 8 views
0

Ich habe eine Präsentationskomponente, die eine Funktion aus ihrer Container-Komponente als Requisite übernimmt. Ich möchte ein ref als ein Argument mit der Funktion zurück an die Container-Komponente zurückgeben. Aber es wird als undefined zurückgegeben.React: Senden ref zurück zur Container-Komponente?

(Was ich will, erreichen, ist die E-Mail senden die Benutzer in das Formular in der Präsentationskomponente Adresse einfügen, zurück zum Container-Komponente, damit ich es dort verarbeiten kann.)

Jeder Vorschlag, wie man machen diese Arbeit?

Container Komponente

class EmailInputContainer extends Component { 
    addEmailToList(childComponent){ 
    console.log(childComponent.refs) 
    } 
    render(){ 
    return(
     <EmailInputView addEmailToList={this.addEmailToList}/> 
    ) 
    } 
} 

Präsentation Komponente

const EmailInputView = (functions) => (
    <Grid style={Styles.emailInputView.container} verticalAlign='middle'> 
    <Cell width='5/12' style={Styles.smallText('black', 1.1, 1.5, 'left')}> 
     <p>Enter your mail and we'll keep you<br />posted with news and updates!</p> 
    </Cell> 
    <Cell width='5/12' align='right'> 
     <form onSubmit={functions.addEmailToList(this)}> 
     <input style={Styles.emailInputForm.emailInput} ref='emailInput' type="text" name="email" placeholder="Your email address" /> 
     <input style={Styles.emailInputForm.submitButton} type="submit" value="Submit" /> 
     </form> 
    </Cell> 
    </Grid> 
) 

Antwort

4

Imho wäre am besten Praxis ein onchange-Handler, um von als Stütze zu Ihrem EmailInputView wie:

class EmailInputContainer extends Component { 

    handleChange: function(event) { 
     this.setState({myEmail: event.target.value}); 
    } 

    render(){ 
     return(
     <EmailInputView onChange={this.handleChange.bind(this)} /> 
    ) 
    } 
} 

und:

<input onChange={this.props.onChange} style={Styles.emailInputForm.emailInput} type="text" /> 

in der EmailInputView selbst. Kompatibel mit

<form onSubmit={this.props.onChange}> 
    ... 
</form> 

zu (havent das Ereignis geprüft u könnte die Prozedur in den EmailInputContainer leicht anpassen müssen).

In diesem Fall müssen Sie nicht ein Ref übergeben, die viel besser mit der Philosophy of reagieren passt. Imho solltest du nie einen Ref so übergeben, wie du es wolltest und nur Refs in der Komponente verwenden, in der du dich befindest, wenn es keinen anderen Weg gibt.

Optinal (wenn u nicht wollen, um das Formular abschicken):

class EmailInput extends Component { 

    onChange(event) { 
    this.setState({myEmail: event.target.value}); 
    } 

    onSubmit() { 
    this.props.onChange(this.state.myEmail); //u should rename the prop i just named it so it fits with the example of the parent component above 
    } 

    render() { 
    return (
     <Cell> 
      <input onChange={this.onChange} /> 
      <button onClick={this.onSubmit} /> 
     </Cell> 
    ); 
    } 

} 

es nicht notwendig ist, ein Formular zu verwenden, überhaupt, wenn Sie nicht wollen, seine verhindern functionalitly danach. Wenn Sie die Daten immer noch ohne Neuladen der Seite posten möchten, müssen Sie sowieso einen Ajax-Aufruf implementieren.

+0

Schön, danke. Warum rufen Sie die Funktion für jeden Tastendruck auf ('onChange') und nicht nur' onSubmit'? Wie höre ich in dieser Lösung den Absenden-Button? Und wie verhindere ichDefault (ich habe 'event.preventDefault() 'ohne Glück versucht)? – allegutta

+0

Ich bin nicht sicher, welche Daten on OnSubmit bekommen, aber aus Grund, es wäre besser, dies zu verwenden, weil Sie es sowieso wissen müssten, wenn das Formular tatsächlich eingereicht wurde und Sie keine Strings mit der halben E-Mail die ganze Zeit behandeln. Versuche es. – Aligertor

+0

Ich war nur auf einen Handler statt einer Ref übergeben - weil das ist der wichtige Punkt, um imho – Aligertor

0

Erfassen Sie in Ihrer Präsentationskomponente den Knoten ref beim Rendern über eine Callback-Funktion, und übergeben Sie den Knotenwert beim Senden an Ihr übergeordnetes Element zurück.

let inputNode 

const EmailInputView = (functions) => (
    <Grid style={Styles.emailInputView.container} verticalAlign='middle'> 

    ... 

    <Cell width='5/12' align='right'> 
     <form 
     onSubmit={() => functions.addEmailToList(inputNode.value)} <-- update here 
     > 
     <input style={Styles.emailInputForm.emailInput} 

      ref={node => inputNode = node} <-- this is what you want 

      type="text" name="email" placeholder="Your email address" /> 
     <input style={Styles.emailInputForm.submitButton} type="submit" value="Submit" /> 
     </form> 
    </Cell> 
    </Grid> 
) 

aktualisieren Sie dann Ihre Handler:

addEmailToList(value){ 
    console.log(value) 
} 

So ist diese Lösung super, vor allem, wenn Sie nicht über einen Elternteil haben, der alles hat Handhabung wie eine Redux Aktion direkt von der Komponente Dispatching, die das hat Eingabefeld. Die Antwort von @ Aligertor ist jedoch genau richtig.

Verwandte Themen