2015-12-18 1 views
5

Ich versuche, eine benutzerdefinierte Checkbox-Komponente (ein Drei-Zustand, eigentlich, aber das ist irrelevant, außer zu sagen, dass ich nicht nur eine Eingabe verwenden), und ich bin mir nicht sicher, wie ich es schaffen kann Ändern Sie "checkedness" aus Klicks auf sich selbst und aus einem Wertsatz, der vom übergeordneten Element herunterkommt.Wie verwalte ich den Status einer React-Komponente, bei der der Status vom übergeordneten Element oder von Ereignissen geändert werden kann?

Derzeit habe ich es als eine autarke Komponente, die eine OnChange-Requisite mit der Handler-Callback, die es aufruft, um den Wert die übergeordnete Komponente nach Klicks sendet. Es verwendet einen Zustand, um die Checkedness zu speichern, auf die das Display verweist.

Wenn es nur ein Display von checkedness wäre, mit Wert von außen verwaltet wird, würde ich Requisiten natürlich verwenden. Wenn es nur eine autarke Checkbox-Komponente wäre, die einen Anfangswert angenommen hätte und dann nur auf Klicks reagiert hätte, würde ich den Status verwenden, wie ich es bin, aber mein Problem ist, dass ich es anklickbar machen möchte, um es ein- und auszuschalten Erlauben Sie dem Elternteil, es auch an- und auszuschalten.

Ich bin ein Anfänger zu Reagieren und die "Reactive Art zu denken", also vermute ich, dass ich gerade dieses Falsche nähere. Ich habe den Eindruck, dass der richtige Weg dafür wäre, dass es sich um eine reine Display-Komponente handelt, die Klicks an die übergeordneten Elemente weiterleitet und im Gegenzug Requisiten-Updates für Wertänderungen vom Vorgänger erhält das würde meiner Meinung nach die Komponente weit weniger wiederverwendbar machen.

Also, wie würde ich eine Checkbox Änderung von internen und Eltern Quellen machen?

Relevante Links sind ebenfalls willkommen.

Antwort

7

Sie können das Kontrollkästchen als stumm Komponente behandeln, was bedeutet, dass es keine internen Zustände hält, erhält aber nur Daten von außen über Requisiten und dann machen Sie. Sie können die detaillierte Definition von dummen Komponenten here sehen.

Inzwischen wird, wenn die Checkbox angeklickt wird, ein solches Ereignis wird von der Komponente Eltern oder Ereignisse Vorfahren behandelt wird, wird diese inverser Datenfluss genannt, die in Facebook Thinking in React Blog-Beitrag beschrieben.

Darüber hinaus zu entscheiden, welche Komponente bestimmte Zustände halten sollte, finde ich die folgenden Richtlinien sehr nützlich:

Denken Sie daran: Reagieren Sie alles über Einweg-Datenfluss ist die Komponentenhierarchie nach unten. Es kann nicht sofort klar sein, welche Komponente welchen Zustand besitzen sollte. Dies ist oft der schwierigste Teil für Neulinge zu verstehen, diese Schritte so folgen, es herauszufinden:

Für jedes Stück Zustand in Ihrer Anwendung:

  • jede Komponente identifizieren, die auf etwas basiert macht dieser Staat.
  • Suchen Sie eine gemeinsame Besitzerkomponente (eine einzelne Komponente vor allem die Komponenten, die den Status in der Hierarchie benötigen).
  • Entweder der gemeinsame Eigentümer oder eine andere Komponente in der Hierarchie sollte den Status besitzen.
  • Wenn Sie keine Komponente finden können, bei der es sinnvoll ist, den Status zu besitzen, erstellen Sie einfach eine neue Komponente, um den Status zu halten und fügen Sie ihn irgendwo in der Hierarchie oberhalb der allgemeinen Eigentümerkomponente hinzu.

Der Pseudo-Code-Schnipsel:

const Checkbox = React.createClass({ 
    // Propagate the event to parents 
    onClick(evt) { 
    if (this.props.handleClick) { 
     this.props.handleClick({checked: evt.target.value}); 
    } 
    }, 

    render() { 
    return (
     this.props.checked ? 
     <Input onClick={this.onClick} type="checkbox" label="Checkbox" checked></Input> : 
     <Input onClick={this.onClick} type="checkbox" label="Checkbox"></Input> 
    ); 
    } 
}); 

const Container = React.createClass({ 
    handleClick(evt) { 
    // Change the container's state, which eventually changes the checkbox's view via props. 
    this.setState({checked: evt.checked}); 
    }, 

    render() { 
    return (
     <div><Checkbox checked={this.state.checked} handleClick={this.handleClick}></Checkbox></div> 
    ); 
    } 
}); 
+0

Ja, das klingt nach dem, was ich tun muss. Ich fange an, meine Gedanken von meinen alten "Eiferbrigaden" -Ideen (wo Daten nach Bedarf von einer einzelnen Komponente behandelt werden) zu mehr von der "zentralen Kontrollpunkt" -Idee zu verschieben, die React verwendet. Ich habe einfach nicht gemerkt, dass Philosophie so allumfassend war, was mein Auflegen war. Und danke für die Artikellinks. – SuperFLEB

3

Sie ändern es nur von den Eltern.

class ParentComponent extends React.Component{ 
    handleChildCheck(){ 
    this.setState({ 
    childChecked: !this.state.childChecked 
    }) 
    } 
    render(){ 
    return(
     <ChildComponent checked={this.state.childChecked} handleCheck={this.handleChildCheck.bind(this)} /> 
    ) 
} 
} 

Nun, wenn Sie den Überprüfungsstatus von den <ChildComponent/> nur this.props.handleCheck() Anruf aus der Bedienelemente Auf diese Weise <ChildComponent/>

zu steuern, wird immer innerhalb der <ChildComponent/> über this.props.handleCheck() im <ParentComponent/> über this.handleChildCheck() zur Verfügung.

+0

Okay, nachdem an, dass suchen und auf meinem eigenen um ein bisschen mehr noodling, ich glaube, ich verstehe. Grundsätzlich sollte die Checkbox-Komponente (das Kind) nur eine Requisite für checkedness übernehmen, sich selbst korrekt anzeigen und alle Interaktionsereignisse (clicks) an einen Parent-Handler weiterleiten (handleChildCheck, in Ihrem Beispiel). Alles andere, einschließlich der Logik, wie das Klicken auf das Kontrollkästchen die Reck-Eigenschaft setzt, sollte im Elternteil behandelt werden und durch Requisiten auf das Kind fallen. Hört sich das richtig an? – SuperFLEB

+0

Ja, richtig. Das entspricht der React-Denkweise! –

-2

Verwenden Sie querySelectorAll, um Ihre Komponenten zu finden. Fügen Sie einen Ereignis-Listener hinzu, um Änderungen zu überwachen. Führen Sie bei Änderung einen anderen querySelectorAll aus, um untergeordnete Elemente zu finden und zu deaktivieren oder zu aktivieren. Dies deckt möglicherweise nicht alle Ihre Bedürfnisse ab, aber es wird Sie in die richtige Richtung bringen. Dies ist einfach Javascript, so dass keine anderen Bibliotheken benötigt werden.

// Finds radios with class on-off and disables 'name-on' elements when 
 
// 'name' is off. 
 

 
function initOfOff() { 
 
    var mains = document.querySelectorAll('.on-off'); 
 

 
    for (var i = 0; i < mains.length; i++) { 
 
    var el = mains[i]; 
 
    var name = el.getAttribute('name'); 
 
    el.addEventListener('click', function() { 
 
     var value = this.getAttribute('value'); 
 
     var children = document.querySelectorAll('.' + name + '-on'); 
 
     for (var i = 0; i < children.length; i++) { 
 
     var child = children[i]; 
 
     child.checked = false; 
 
     if (value == "off") { 
 
      child.setAttribute('disabled', 'disabled'); 
 
     } else { 
 
      child.removeAttribute('disabled'); 
 
     } 
 
     } 
 
    }); 
 
    } 
 
} 
 
initOfOff()
<form name='myform'>power 
 
    <input type='radio' value='on' class='on-off' name='power'>ON | 
 
    <input type='radio' value='off' class='on-off' name='power'>Off 
 
    <dir>lights 
 

 
    <input type='radio' value='on' class='power-on' name='lights'>ON | 
 
    <input type='radio' value='off' class='power-on' name='lights'>OFF 
 
    </dir> 
 
</form>

+0

Entschuldigung, ich hätte erwähnen sollen, dass ich nach einer React-spezifischen Lösung suche. (Ich poste nicht wirklich so viel zu SO, deshalb bin ich immer noch ein wenig verschwommen mit den Details der Kategorisierung.) Ich habe die Tags und den Titel entsprechend geändert. Danke, dass du dich darin vertieft hast. – SuperFLEB

Verwandte Themen