2015-01-09 8 views
110

Ich habe die folgende Struktur:Wie Kinder Zustand Zugriff in Reaktion?

FormEditor - hält mehr FieldEditor FieldEditor - bearbeitet ein Feld der Form und verschiedene Werte über sie zu speichern darin Zustand ist

Wenn eine Taste innerhalb FormEditor geklickt wird, mag ich der Lage sein, Informationen über die Felder von allen FieldEditor Komponenten zu sammeln, Informationen, die in ihrem Zustand ist, und das alles innerhalb FormEditor haben.

Ich überlegte, die Informationen über die Felder außerhalb von FieldEditor 's Zustand zu speichern und es in FormEditor' s Zustand stattdessen zu setzen. das würde FormEditor erfordern jedoch zu jedem der es FieldEditor Komponenten zu hören, wie sie und ihre Informationen ändern darin Zustand.

kann ich nicht auf nur die anstelle Zustand der Kinder? Ist es ideal?

+4

* „Kann ich nicht stattdessen nur den Zustand der Kinder zugreifen? Ist es ideal?“ * Nr Staat etwas Inneres und sollte nicht auslaufen nach außen ist. Sie können Accessor-Methoden für Ihre Komponente implementieren, aber selbst das ist nicht ideal. –

+0

@FelixKling Dann schlagen Sie vor, dass der ideale Weg für die Kommunikation von Kind zu Eltern nur Ereignisse sind? –

+3

Ja, Ereignisse sind ein Weg. Oder haben eine unidirektionale Datenfluss wie Flux fördert: https://facebook.github.io/flux/ –

Antwort

69

Wenn Sie bereits onChange-Handler für die einzelnen FieldEditors haben, sehe ich nicht, warum Sie den Status nicht einfach in die FormEditor-Komponente verschieben und von dort einen Rückruf an die FieldEditors übergeben können, die den übergeordneten Status aktualisieren . Das scheint mir ein reaktiverer Weg zu sein.

Etwas entlang der Linie dieser vielleicht:

var FieldEditor = React.createClass({ 
    handleChange: function(event) { 
    var text = event.target.value; 
    this.props.onChange(this.props.id, text); 
    }, 

    render: function() { 
    return (
     <div className="field-editor"> 
     <input onChange={this.handleChange} value={this.props.value}/> 
     </div> 
    ); 
    } 
}); 

var FormEditor = React.createClass({ 
    getInitialState: function() { 
    return {}; 
    }, 
    handleFieldChange: function(fieldId, value) { 
    var newState = {}; 
    newState[fieldId] = value; 

    this.setState(newState); 
    }, 

    render: function() { 
    var fields = this.props.fields.map(function(field) { 
     var props = { 
     id: field, 
     onChange: this.handleFieldChange, 
     value: this.state[field] 
     } 
     return <FieldEditor {...props} /> 
    }, this); 

    return (
     <div> 
     {fields} 
     <div>{JSON.stringify(this.state)}</div> 
     </div> 
    ); 
    } 
}); 

var App = React.createClass({ 
    render: function() { 
    var fields = ["field1", "field2", "anotherField"]; 

    return (
     <FormEditor fields={fields}/> 
    ); 
    } 
}); 


React.render(<App/>, document.body); 

http://jsbin.com/fabonujenu/8/edit

Edit: Statt FieldEditor Elemente als Kinder FormEditor zugeben ich einfach eine Liste von fieldIds geben und sie in der FormEditor schaffen statt. Dies macht es einfacher, dynamisch FieldEditors hinzufügen und macht die Render-Methode von FormEditor weniger wonkey.

+0

, dies zu tun ist nützlich für onChange, aber nicht so viel in onSubmit. –

+1

@ 190290000RubleMan bin ich nicht sicher, was du meinst, aber da die onChange Handler auf den einzelnen Feldern sicherstellen, dass Sie immer die kompletten Formulardaten in Ihrem Zustand in Ihrer FormEditor Komponente haben, würde Ihr onSubmit nur enthält so etwas wie 'MyApi. SaveStuff (this.state); '. Wenn Sie ein bisschen mehr ausarbeiten, kann ich Ihnen vielleicht eine bessere Antwort geben :) –

+0

Angenommen, ich habe ein Formular mit 3 Feldern unterschiedlichen Typs, jeder mit einer eigenen Validierung. Ich möchte jedes von ihnen vor dem Einreichen validieren. Wenn die Validierung fehlschlägt, sollte jedes Feld, das einen Fehler aufweist, neu gerendert werden. Ich habe nicht herausgefunden, wie ich das mit Ihrer vorgeschlagenen Lösung machen soll, aber vielleicht gibt es einen Weg! –

121

Wenn Sie den Status einer Komponente Kinder zugreifen möchten, können Sie eine Eigenschaft ref jedem Kind genannt zuweisen. Diese Eigenschaft verwendet eine Callback-Funktion, die eine Referenz an die angefügte Komponente übergeben wird. Dieser Rückruf wird ausgeführt, unmittelbar nachdem die Komponente eingehängt oder ausgehängt wurde.

Zum Beispiel:

ES5:

<FieldEditor 
    ref={function(fieldEditor1){this.fieldEditor1 = fieldEditor1;}} 
    {...props} 
/> 

ES6:

<FieldEditor 
    ref={(fieldEditor1) => {this.fieldEditor1 = fieldEditor1;} 
    {...props} 
/> 

In diesen Beispielen wird die Bezugnahme auf die übergeordnete Komponente gespeichert wird. Um diese Komponente in Ihrem Code aufrufen, können Sie verwenden:

this.fieldEditor1 

und dann this.fieldEditor1.state verwenden, um den Zustand zu bekommen.

Eine Sache zu beachten, stellen Sie sicher, dass Ihr Kind Komponente geleistet hat, bevor Sie versuchen, darauf zuzugreifen^_^

Wenn Sie mehr lesen möchten über Ref Eigenschaft Reaktion, lesen Sie in diesem page von Facebook.

Stellen Sie sicher, dass Sie den Abschnitt "Don't Overuse Refs" gelesen haben, der besagt, dass Sie die state des Kindes nicht verwenden sollten, um Dinge "passieren zu lassen".

this helps^_^

Edit: Changed Antwort Rückruf Refs zu verwenden, wie bespannen Refs im Gegensatz String Refs in einer zukünftigen Version entfernt React.js wahrscheinlich (siehe Refs and the DOM für weitere Details).

+5

auch nette kleine Leckerbissen, können Sie Funktionen von 'this.refs.yourComponentNameHere' nennen. Ich habe es nützlich gefunden, um Status über Funktionen zu ändern. Beispiel: 'this.refs.textInputField.clearInput();' –

+7

Vorsicht (aus der Dokumentation): * Refs sind eine gute Möglichkeit, eine Nachricht an eine bestimmte Kind-Instanz in einer Weise zu senden, die unbequem wäre Streaming Reaktive 'Requisiten' und' State'. Sie sollten jedoch nicht Ihre bevorzugte Abstraktion sein, um Daten durch Ihre Anwendung fließen zu lassen. Standardmäßig verwendet den Reactive Datenfluss und sparen 'ref's für Anwendungsfälle, die von Natur aus nicht-reaktiv sind. * – Lynn

+2

ich nur Zustand erhalten, die innerhalb Konstruktor (nicht auf dem aktuellen Stand Zustand) –

Verwandte Themen