Übergeben Sie Requisiten an die übergeordnete Komponente in React.js

295

Gibt es nicht eine einfache Möglichkeit, ein Kind propsmithilfe von Ereignissen in React.js an seine Eltern zu übergeben?

var Child = React.createClass({
  render: function() {
    <a onClick={this.props.onClick}>Click me</a>
  }
});

var Parent = React.createClass({
  onClick: function(event) {
    // event.component.props ?why is this not available?
  },
  render: function() {
    <Child onClick={this.onClick} />
  }
});

Ich weiß, dass Sie gesteuerte Komponenten verwenden können, um den Wert eines Eingangs zu übergeben, aber es wäre schön, das gesamte Kit n 'Kaboodle zu übergeben. Manchmal enthält die untergeordnete Komponente eine Reihe von Informationen, die Sie lieber nicht nachschlagen müssen.

Vielleicht gibt es eine Möglichkeit, die Komponente an das Ereignis zu binden?

UPDATE - 01.09.2015

Nachdem ich React über ein Jahr lang verwendet habe und von Sebastien Lorbers Antwort beflügelt wurde, bin ich zu dem Schluss gekommen, dass das Übergeben von untergeordneten Komponenten als Argumente für Funktionen in Eltern weder React noch eine gute Idee ist. Ich habe die Antwort gewechselt.

KendallB
quelle
Es gibt verschiedene Antworten auf ähnliche Probleme ( hier und hier ), aber keine davon scheint besonders elegant zu sein
Bojangles
Ich stimme zu - es ist großartig, Ereignisse in der Kette weiterzugeben, aber es wäre großartig zu wissen, von welcher Komponente das Ereignis stammt.
KendallB
Bitte werfen Sie einen Blick auf meine Antworten, da ich denke, dass die akzeptierte Antwort nicht gut genug ist. stackoverflow.com/a/31756470/82609
Sebastien Lorber
1
kit n 'kaboodle - Um alles inklusive zu bekommen. Um alle Schnickschnack zu bekommen. Die Kombination. urbandictionary.com/define.php?term=kit%20and%20caboodle
Filip Bartuzi

Antworten:

268

Bearbeiten : In den Endbeispielen finden Sie aktualisierte ES6-Beispiele.

Diese Antwort behandelt einfach den Fall einer direkten Eltern-Kind-Beziehung. Wenn Eltern und Kind möglicherweise viele Vermittler haben, überprüfen Sie diese Antwort .

Andere Lösungen verfehlen den Punkt

Während sie noch gut funktionieren, fehlt anderen Antworten etwas sehr Wichtiges.

Gibt es nicht eine einfache Möglichkeit, die Requisiten eines Kindes mithilfe von Ereignissen in React.js an die Eltern weiterzugeben?

Der Elternteil hat bereits diese Kinderstütze! : Wenn das Kind eine Requisite hat, dann deshalb, weil sein Elternteil dem Kind diese Requisite zur Verfügung gestellt hat! Warum soll das Kind die Requisite an die Eltern zurückgeben, während die Eltern diese Requisite offensichtlich bereits haben?

Bessere Umsetzung

Kind : Es muss wirklich nicht komplizierter sein.

var Child = React.createClass({
  render: function () {
    return <button onClick={this.props.onClick}>{this.props.text}</button>;
  },
});

Eltern mit einem einzelnen Kind : Verwenden des Werts, der an das Kind übergeben wird

var Parent = React.createClass({
  getInitialState: function() {
     return {childText: "Click me! (parent prop)"};
  },
  render: function () {
    return (
      <Child onClick={this.handleChildClick} text={this.state.childText}/>
    );
  },
  handleChildClick: function(event) {
     // You can access the prop you pass to the children 
     // because you already have it! 
     // Here you have it in state but it could also be
     //  in props, coming from another parent.
     alert("The Child button text is: " + this.state.childText);
     // You can also access the target of the click here 
     // if you want to do some magic stuff
     alert("The Child HTML is: " + event.target.outerHTML);
  }
});

JsFiddle

Elternteil mit Liste der Kinder : Sie haben immer noch alles, was Sie brauchen, auf dem Elternteil und müssen das Kind nicht komplizierter machen.

var Parent = React.createClass({
  getInitialState: function() {
     return {childrenData: [
         {childText: "Click me 1!", childNumber: 1},
         {childText: "Click me 2!", childNumber: 2}
     ]};
  },
  render: function () {
    var children = this.state.childrenData.map(function(childData,childIndex) {
        return <Child onClick={this.handleChildClick.bind(null,childData)} text={childData.childText}/>;
    }.bind(this));
    return <div>{children}</div>;
  },

  handleChildClick: function(childData,event) {
     alert("The Child button data is: " + childData.childText + " - " + childData.childNumber);
     alert("The Child HTML is: " + event.target.outerHTML);
  }
});

JsFiddle

Es ist auch möglich, zu verwenden this.handleChildClick.bind(null,childIndex)und dann zu verwendenthis.state.childrenData[childIndex]

Beachten Sie, dass wir mit einem nullKontext binden, da React andernfalls eine Warnung bezüglich seines Autobindungssystems ausgibt . Die Verwendung von null bedeutet, dass Sie den Funktionskontext nicht ändern möchten. Siehe auch .

Über Kapselung und Kopplung in anderen Antworten

Dies ist für mich eine schlechte Idee in Bezug auf Kopplung und Einkapselung:

var Parent = React.createClass({
  handleClick: function(childComponent) {
     // using childComponent.props
     // using childComponent.refs.button
     // or anything else using childComponent
  },
  render: function() {
    <Child onClick={this.handleClick} />
  }
});

Verwenden von Requisiten : Wie oben erläutert, haben Sie die Requisiten bereits im übergeordneten Element, sodass es sinnlos ist, die gesamte untergeordnete Komponente für den Zugriff auf Requisiten zu übergeben.

Verwenden von Refs : Sie haben bereits das Klickziel im Ereignis, und in den meisten Fällen reicht dies aus. Außerdem hätten Sie einen Ref direkt für das Kind verwenden können:

<Child ref="theChild" .../>

Und greifen Sie mit auf den DOM-Knoten im übergeordneten Knoten zu

React.findDOMNode(this.refs.theChild)

In fortgeschritteneren Fällen, in denen Sie auf mehrere Refs des untergeordneten Elements im übergeordneten Element zugreifen möchten, kann das untergeordnete Element alle dom-Knoten direkt im Rückruf übergeben.

Die Komponente verfügt über eine Schnittstelle (Requisiten), und der Elternteil sollte nichts über die innere Arbeitsweise des Kindes annehmen, einschließlich seiner inneren DOM-Struktur oder der DOM-Knoten, für die er Refs deklariert. Ein Elternteil, der eine Referenz eines Kindes verwendet, bedeutet, dass Sie die beiden Komponenten eng miteinander verbinden.

Um das Problem zu veranschaulichen, nehme ich dieses Zitat über das Shadow DOM , das in Browsern verwendet wird, um Dinge wie Schieberegler, Bildlaufleisten, Videoplayer zu rendern ...:

Sie haben eine Grenze zwischen dem, was Sie als Webentwickler erreichen können, und den Implementierungsdetails geschaffen, auf die Sie keinen Zugriff haben. Der Browser kann diese Grenze jedoch nach Belieben überschreiten. Mit dieser Grenze konnten sie alle HTML-Elemente mit denselben guten alten Webtechnologien aus den Divs und Spans erstellen, genau wie Sie es tun würden.

Das Problem besteht darin, dass es sehr schwierig ist, das untergeordnete Element zu überarbeiten, ohne dass sich dies auf das übergeordnete Element auswirkt, wenn Sie die untergeordneten Implementierungsdetails in das übergeordnete Element übertragen. Dies bedeutet, dass dies als Bibliotheksautor (oder als Browser-Editor mit Shadow DOM) sehr gefährlich ist, da Sie dem Client zu viel Zugriff gewähren, was es sehr schwierig macht, Code zu aktualisieren, ohne die Retrokompatibilität zu beeinträchtigen.

Wenn Chrome seine Bildlaufleiste implementiert hat, mit der der Client auf die inneren Domänenknoten dieser Bildlaufleiste zugreifen kann, bedeutet dies, dass der Client möglicherweise die Möglichkeit hat, diese Bildlaufleiste einfach zu beschädigen, und dass Apps leichter beschädigt werden, wenn Chrome nach dem Refactoring die automatische Aktualisierung durchführt Bildlaufleiste ... Stattdessen bieten sie nur Zugriff auf einige sichere Dinge wie das Anpassen einiger Teile der Bildlaufleiste mit CSS.

Über die Verwendung von etwas anderem

Die gesamte Komponente in der Callback - Passing ist gefährlich und Anfänger Entwickler führen können sehr seltsame Dinge zu tun , wie der Aufruf childComponent.setState(...)oder childComponent.forceUpdate(), oder es neue Variablen, innerhalb des übergeordneten, so dass die ganze app viel schwieriger zu Grund , sich über die Zuordnung.


Bearbeiten: ES6-Beispiele

Da viele Leute jetzt ES6 verwenden, finden Sie hier dieselben Beispiele für die ES6-Syntax

Das Kind kann sehr einfach sein:

const Child = ({
  onClick, 
  text
}) => (
  <button onClick={onClick}>
    {text}
  </button>
)

Das Elternteil kann entweder eine Klasse sein (und es kann schließlich den Staat selbst verwalten, aber ich gebe es hier als Requisiten weiter:

class Parent1 extends React.Component {
  handleChildClick(childData,event) {
     alert("The Child button data is: " + childData.childText + " - " + childData.childNumber);
     alert("The Child HTML is: " + event.target.outerHTML);
  }
  render() {
    return (
      <div>
        {this.props.childrenData.map(child => (
          <Child
            key={child.childNumber}
            text={child.childText} 
            onClick={e => this.handleChildClick(child,e)}
          />
        ))}
      </div>
    );
  }
}

Es kann aber auch vereinfacht werden, wenn der Status nicht verwaltet werden muss:

const Parent2 = ({childrenData}) => (
  <div>
     {childrenData.map(child => (
       <Child
         key={child.childNumber}
         text={child.childText} 
         onClick={e => {
            alert("The Child button data is: " + child.childText + " - " + child.childNumber);
                    alert("The Child HTML is: " + e.target.outerHTML);
         }}
       />
     ))}
  </div>
)

JsFiddle


PERF-WARNUNG (gilt für ES5 / ES6): Wenn Sie PureComponentoder verwenden shouldComponentUpdate, werden die oben genannten Implementierungen nicht standardmäßig optimiert onClick={e => doSomething()}, da sie während der Renderphase verwendet oder direkt gebunden werden, da bei jedem Rendern des übergeordneten Elements eine neue Funktion erstellt wird. Wenn dies ein perfekter Engpass in Ihrer App ist, können Sie die Daten an die untergeordneten Elemente übergeben und sie innerhalb des "stabilen" Rückrufs (der für die übergeordnete Klasse festgelegt und an den Klassenkonstruktor gebunden ist this) erneut einfügen, damit die PureComponentOptimierung aktiviert werden kann, oder Sie Sie können Ihre eigenen implementieren shouldComponentUpdateund den Rückruf in der Requisitenvergleichsprüfung ignorieren.

Sie können auch die Recompose- Bibliothek verwenden, die Komponenten höherer Ordnung bereitstellt, um fein abgestimmte Optimierungen zu erzielen:

// A component that is expensive to render
const ExpensiveComponent = ({ propA, propB }) => {...}

// Optimized version of same component, using shallow comparison of props
// Same effect as React's PureRenderMixin
const OptimizedComponent = pure(ExpensiveComponent)

// Even more optimized: only updates if specific prop keys have changed
const HyperOptimizedComponent = onlyUpdateForKeys(['propA', 'propB'])(ExpensiveComponent)

In diesem Fall können Sie die untergeordnete Komponente optimieren, indem Sie Folgendes verwenden:

const OptimizedChild = onlyUpdateForKeys(['text'])(Child)
Sebastien Lorber
quelle
1
Ja, nachdem ich das letzte Jahr mit React verbracht habe, stimme ich zu - es gibt keinen guten Grund, instanziierte Komponenten über Funktionen weiterzugeben. Ich werde meine eigene Antwort ablehnen. Ich bin auch bereit, die Antwort mit möglicherweise einigen Änderungen zu ändern: Ihre "Bessere Implementierung" geht nicht auf den tatsächlichen Grund ein, aus dem diese Frage gestellt wurde: "Woher weiß ich, welches meiner Kinder aus einer Gruppe ausgewählt wurde?" Flux ist die Antwort für jede App mit anständiger Größe. In kleinen Apps ist es jedoch hilfreich, Werte (keine Komponenten) über eine Funktion in der Anrufkette zu übergeben props. Zustimmen?
KendallB
@ KendallB froh, dass Sie meiner Antwort zustimmen :) How do I know which of my children was chosen among a group?Dies ist nicht wirklich Teil der ursprünglichen Frage, aber ich habe die Lösung in meine Antwort aufgenommen. Im Gegensatz zu Ihrer Bearbeitung ist es meines Erachtens nicht erforderlich, das untergeordnete Element zu ändern, selbst wenn Sie sich mit einer Liste befassen, da Sie diese binddirekt im übergeordneten Element verwenden können.
Sebastien Lorber
Ich habe Ihre Antwort bearbeitet, den Teil über Refs. omerwazir.com/posts/react-getdomnode-replaced-with-findDOMNode
ffxsam
Hi @SebastienLorber Ich komme aus der Zukunft. In Bezug auf diese Zeile, die onClick={this.handleChildClick.bind(null,childData)}Sie über Autobindung erwähnt haben, gilt dies auch jetzt noch, da React nicht im Klassenmodell enthalten ist . Ich habe viel gelesen, aber dieser Teil verwirrt mich immer noch. Ich verwende ES6 class modeldurch die Art und Weise, also habe ich nullauf thisund mein Code scheinen immer noch zu arbeiten. Wie würden Sie diesen Teil Ihres Codes in einen ES6-Stil übersetzen?
JohnnyQ
Ich kämpfe auch darum, dass dies in der neuesten Reaktion funktioniert. Was muss sich ändern?
Hussein Duvigneau
143

Update (01.09.15): Das OP hat diese Frage zu einem beweglichen Ziel gemacht. Es wurde erneut aktualisiert. Daher fühle ich mich dafür verantwortlich, meine Antwort zu aktualisieren.

Zunächst eine Antwort auf Ihr Beispiel:

Ja, das ist möglich.

Sie können dies lösen, indem Sie Child's onClickwie folgt aktualisieren this.props.onClick.bind(null, this):

var Child = React.createClass({
  render: function () {
    return <a onClick={this.props.onClick.bind(null, this)}>Click me</a>;
  }
});

Der Ereignishandler in Ihrem übergeordneten Element kann dann wie folgt auf die Komponente und das Ereignis zugreifen:

  onClick: function (component, event) {
    // console.log(component, event);
  },

JSBin-Schnappschuss


Aber die Frage selbst ist irreführend

Eltern kennen bereits Kinder props.

Dies ist im angegebenen Beispiel nicht klar, da tatsächlich keine Requisiten bereitgestellt werden. Dieser Beispielcode unterstützt möglicherweise die gestellte Frage besser:

var Child = React.createClass({
  render: function () {
    return <a onClick={this.props.onClick}> {this.props.text} </a>;
  }
});

var Parent = React.createClass({
  getInitialState: function () {
    return { text: "Click here" };
  },
  onClick: function (event) {
    // event.component.props ?why is this not available? 
  },
  render: function() {
    return <Child onClick={this.onClick} text={this.state.text} />;
  }
});

In diesem Beispiel wird viel deutlicher, dass Sie bereits wissen, was die Requisiten von Child sind.

JSBin-Schnappschuss


Wenn es wirklich darum geht, die Requisiten eines Kindes zu benutzen ...

Wenn es wirklich darum geht, die Requisiten eines Kindes zu verwenden, können Sie jegliche Verbindung mit Child insgesamt vermeiden.

JSX verfügt über eine API für Spread-Attribute, die ich häufig für Komponenten wie Child verwende. Es nimmt alle propsund wendet sie auf eine Komponente an. Kind würde so aussehen:

var Child = React.createClass({
  render: function () {
    return <a {...this.props}> {this.props.text} </a>;
  }
});

So können Sie die Werte direkt im übergeordneten Element verwenden:

var Parent = React.createClass({
  getInitialState: function () {
    return { text: "Click here" };
  },
  onClick: function (text) {
    alert(text);
  },
  render: function() {
    return <Child onClick={this.onClick.bind(null, this.state.text)} text={this.state.text} />;
  }
});

JSBin-Schnappschuss


Es ist keine zusätzliche Konfiguration erforderlich, wenn Sie zusätzliche untergeordnete Komponenten anschließen

var Parent = React.createClass({
  getInitialState: function () {
    return {
      text: "Click here",
      text2: "No, Click here",
    };
  },
  onClick: function (text) {
    alert(text);
  },
  render: function() {
    return <div>
      <Child onClick={this.onClick.bind(null, this.state.text)} text={this.state.text} />
      <Child onClick={this.onClick.bind(null, this.state.text2)} text={this.state.text2} />
    </div>;
  }
});

JSBin-Schnappschuss

Aber ich vermute, dass dies nicht Ihr eigentlicher Anwendungsfall ist. Also lasst uns weiter graben ...


Ein robustes praktisches Beispiel

Die generische Natur des bereitgestellten Beispiels ist schwer zu besprechen. Ich habe eine Komponente erstellt, die eine praktische Verwendung für die obige Frage demonstriert und in einer sehr reaktiven Weise implementiert wurde Weise :

Arbeitsbeispiel für DTServiceCalculator
DTServiceCalculator Repo

Diese Komponente ist ein einfacher Service-Rechner. Sie stellen ihm eine Liste von Diensten (mit Namen und Preisen) zur Verfügung und er berechnet die Summe der ausgewählten Preise.

Kinder sind selig unwissend

ServiceItemist die untergeordnete Komponente in diesem Beispiel. Es gibt nicht viele Meinungen über die Außenwelt. Es sind einige Requisiten erforderlich , von denen eine eine Funktion ist, die beim Klicken aufgerufen werden muss.

<div onClick={this.props.handleClick.bind(this.props.index)} />

Es wird nichts anderes getan, als den bereitgestellten handleClickRückruf mit der bereitgestellten index[ Quelle ] aufzurufen .

Eltern sind Kinder

DTServicesCalculatorist die übergeordnete Komponente ist dieses Beispiel. Es ist auch ein Kind. Lass uns nachsehen.

DTServiceCalculatorErstellt eine Liste der untergeordneten Komponenten ServiceItemund stellt ihnen Requisiten zur Verfügung [ Quelle ]. Es ist die übergeordnete Komponente von, ServiceItemaber es ist die untergeordnete Komponente der Komponente, die die Liste übergibt. Es besitzt nicht die Daten. Daher delegiert es erneut die Behandlung der Komponente an die Quelle der übergeordneten Komponente

<ServiceItem chosen={chosen} index={i} key={id} price={price} name={name} onSelect={this.props.handleServiceItem} />

handleServiceItemerfasst den vom Kind übergebenen Index und stellt ihn seinem übergeordneten [ Quelle ] zur Verfügung.

handleServiceClick (index) {
  this.props.onSelect(index);
}

Die Besitzer wissen alles

Das Konzept der „Eigentümerschaft“ spielt in React eine wichtige Rolle. Ich empfehle mehr darüber zu lesen hier .

In dem Beispiel, das ich gezeigt habe, delegiere ich die Behandlung eines Ereignisses so lange im Komponentenbaum, bis wir zu der Komponente gelangen, der der Status gehört.

Wenn wir endlich dort ankommen, behandeln wir die Auswahl / Abwahl des Status wie folgt: [ Quelle ]:

handleSelect (index) {
  let services = […this.state.services];
  services[index].chosen = (services[index].chosen) ? false : true;
  this.setState({ services: services });
}


Fazit

Versuchen Sie, Ihre äußersten Komponenten so undurchsichtig wie möglich zu halten. Stellen Sie sicher, dass sie nur sehr wenige Einstellungen dazu haben, wie eine übergeordnete Komponente sie implementieren möchte.

Achten Sie darauf, wem die von Ihnen manipulierten Daten gehören. In den meisten Fällen müssen Sie die Ereignisbehandlung im Baum an die Komponente delegieren, die diesen Status besitzt .

Nebenbei: Das Flux-Muster ist ein guter Weg, um diese Art der erforderlichen Verbindung in Apps zu reduzieren.

chantastisch
quelle
Vielen Dank für die prägnante Antwort, es hat mir wirklich geholfen, React ein bisschen besser zu verstehen! Ich habe eine Frage in die gleiche Richtung. Ich benutze Flux für Pub / Sub. Anstatt den Child-Ereignishandler wie in Ihrem Beispiel an das übergeordnete Element zu übergeben, können Sie dies als 'Aktion' implementieren und darauf warten. Würden Sie dies als eine gute Alternative und Verwendung von Flux betrachten?
Pathsofdesign
1
Danke @Pathsofdesign! Es würde davon abhängen. Flux hat dieses Konzept von Controller-Views. In diesem Beispiel Parentkönnte es sich um eine solche Controller-Ansicht handeln, während Childes sich nur um eine dumme Ansicht (Komponente) handelt. Nur Controller-Views sollten Kenntnisse über die Anwendung haben. In diesem Fall würde passieren Sie noch die Aktion aus , Parentum Childals Stütze. In Bezug auf die Aktion selbst verfügt Flux über ein stark vorgeschriebenes Muster für die Interaktion zwischen Aktionen, um Ansichten zu aktualisieren. facebook.github.io/flux/docs/…
chantastisch
1
onClick={this.onClick.bind(null, this.state.text)}Keine Notwendigkeit, den Status zu binden, da der Elternteil dies hat. also wird einfach onClick={this.onClick}funktionieren. wo onClick = ()=>{const text = this.state.text;..}in Eltern
Shishir Arora
25

Es scheint, dass es eine einfache Antwort gibt. Bedenken Sie:

var Child = React.createClass({
  render: function() {
    <a onClick={this.props.onClick.bind(null, this)}>Click me</a>
  }
});

var Parent = React.createClass({
  onClick: function(component, event) {
    component.props // #=> {Object...}
  },
  render: function() {
    <Child onClick={this.onClick} />
  }
});

Der Schlüssel ruft das vom übergeordneten Element bind(null, this)übergebene this.props.onClickEreignis auf. Jetzt akzeptiert die onClick-Funktion Argumente componentUND event. Ich denke, das ist das Beste von allen Welten.

UPDATE: 01.09.2015

Dies war eine schlechte Idee: Es war nie ein guter Weg, die Implementierungsdetails des Kindes an die Eltern weiterzuleiten. Siehe Sebastien Lorbers Antwort.

KendallB
quelle
Sind die Argumente nicht falsch (getauschte Orte)?
Der Surrican
1
@ TheSurrican Nein, es ist vollkommen in Ordnung. Das erste Argument ist an thisdie Funktion gebunden (die ohnehin nicht benötigt wird), und das zweite Argument wird beim Aufruf von onClick als erstes Argument vorangestellt.
Manmal
13

Die Frage ist, wie Argumente von der untergeordneten an die übergeordnete Komponente übergeben werden. Dieses Beispiel ist einfach zu verwenden und zu testen:

//Child component
class Child extends React.Component {
    render() {
        var handleToUpdate  =   this.props.handleToUpdate;
        return (<div><button onClick={() => handleToUpdate('someVar')}>Push me</button></div>
        )
    }
}

//Parent component
class Parent extends React.Component {
    constructor(props) {
        super(props);
        var handleToUpdate  = this.handleToUpdate.bind(this);
    }

    handleToUpdate(someArg){
        alert('We pass argument from Child to Parent: \n' + someArg);
    }

    render() {
        var handleToUpdate  =   this.handleToUpdate;
        return (<div>
          <Child handleToUpdate = {handleToUpdate.bind(this)} />
        </div>)
    }
}

if(document.querySelector("#demo")){
    ReactDOM.render(
        <Parent />,
        document.querySelector("#demo")
    );
}

Schauen Sie sich JSFIDDLE an

römisch
quelle
In meinem Fall vergesse es, die Rückruffunktion an click () zu übergeben
Long Nguyen
6

Grundsätzlich verwenden Sie Requisiten, um Informationen an und von Kind und Eltern zu senden.

Lassen Sie mich zu all den wunderbaren Antworten ein einfaches Beispiel geben, in dem die Übergabe von Werten von der untergeordneten an die übergeordnete Komponente in React erläutert wird

App.js.

class App extends React.Component {
      constructor(){
            super();
            this.handleFilterUpdate = this.handleFilterUpdate.bind(this);
            this.state={name:'igi'}
      }
      handleFilterUpdate(filterValue) {
            this.setState({
                  name: filterValue
            });
      }
   render() {
      return (
        <div>
            <Header change={this.handleFilterUpdate} name={this.state.name} />
            <p>{this.state.name}</p>
        </div>
      );
   }
}

Header.js

class Header extends React.Component {
      constructor(){
            super();
            this.state={
                  names: 'jessy'
            }
      }
      Change(event) {

      // this.props.change(this.state.names);
      this.props.change('jessy');
  }

   render() {
      return (
       <button onClick={this.Change.bind(this)}>click</button>

      );
   }
}

Main.js

import React from 'react';
import ReactDOM from 'react-dom';

import App from './App.jsx';

ReactDOM.render(<App />, document.getElementById('app'));

Jetzt können Sie Werte von Ihrem Client an den Server übergeben.

Schauen Sie sich die Änderungsfunktion in der Header.js an

Change(event) {
      // this.props.change(this.state.names);
      this.props.change('jessy');
  }

Auf diese Weise übertragen Sie Werte in die Requisiten vom Client zum Server

Ignatius Andrew
quelle
Darf ich wissen, dass Sie auf diese Weise Werte vom Client auf den Server in die Requisiten übertragen. Was meinen Sie mit dieser Aussage
G1P
2

Hier ist eine einfache 3-Schritt-ES6-Implementierung unter Verwendung der Funktionsbindung im übergeordneten Konstruktor. Dies ist der erste Weg, den das offizielle Reaktionstutorial empfiehlt (es gibt auch eine Syntax für Felder öffentlicher Klassen, die hier nicht behandelt wird). All diese Informationen finden Sie hier https://reactjs.org/docs/handling-events.html

Binden von Elternfunktionen, damit Kinder sie anrufen können (und Daten an die Eltern weitergeben !: D)

  1. Stellen Sie sicher, dass Sie im übergeordneten Konstruktor die Funktion binden, die Sie im übergeordneten Konstruktor erstellt haben
  2. Übergeben Sie die gebundene Funktion als Requisite an das Kind (kein Lambda, da wir einen Ref übergeben, um zu funktionieren)
  3. Rufen Sie die gebundene Funktion von einem untergeordneten Ereignis aus auf (Lambda! Wir rufen die Funktion auf, wenn das Ereignis ausgelöst wird. Wenn wir dies nicht tun, wird die Funktion automatisch beim Laden ausgeführt und beim Ereignis nicht ausgelöst.)

Übergeordnete Funktion

handleFilterApply(filterVals){} 

Übergeordneter Konstruktor

this.handleFilterApply = this.handleFilterApply.bind(this);

Requisite an Kind übergeben

onApplyClick = {this.handleFilterApply}

Untergeordneter Ereignisanruf

onClick = {() => {props.onApplyClick(filterVals)}
Jordan H.
quelle
0

Dies ist ein Beispiel ohne Verwendung des onClick-Ereignisses. Ich übergebe dem Kind einfach eine Rückruffunktion durch Requisiten. Mit diesem Rückruf sendet der untergeordnete Anruf auch Daten zurück. Die Beispiele in den Dokumenten haben mich inspiriert .

Kleines Beispiel (dies ist in einer tsx-Datei, daher müssen Requisiten und Zustände vollständig deklariert werden. Ich habe einige Logik aus den Komponenten gelöscht, damit es weniger Code gibt).

* Update: Wichtig ist, dies an den Rückruf zu binden, andernfalls hat der Rückruf den Umfang des untergeordneten und nicht des übergeordneten Rückrufs. Einziges Problem: Es ist der "alte" Elternteil ...

SymptomChoser ist der Elternteil:

interface SymptomChooserState {
  // true when a symptom was pressed can now add more detail
  isInDetailMode: boolean
  // since when user has this symptoms
  sinceDate: Date,
}

class SymptomChooser extends Component<{}, SymptomChooserState> {

  state = {
    isInDetailMode: false,
    sinceDate: new Date()
  }

  helloParent(symptom: Symptom) {
    console.log("This is parent of: ", symptom.props.name);
    // TODO enable detail mode
  }

  render() {
    return (
      <View>
        <Symptom name='Fieber' callback={this.helloParent.bind(this)} />
      </View>
    );
  }
}

Symptom ist das Kind (in den Requisiten des Kindes habe ich die Rückruffunktion deklariert, in der Funktion selectedSymptom wird der Rückruf aufgerufen):

interface SymptomProps {
  // name of the symptom
  name: string,
  // callback to notify SymptomChooser about selected Symptom.
  callback: (symptom: Symptom) => void
}

class Symptom extends Component<SymptomProps, SymptomState>{

  state = {
    isSelected: false,
    severity: 0
  }

  selectedSymptom() {
    this.setState({ isSelected: true });
    this.props.callback(this);
  }

  render() {
    return (
      // symptom is not selected
      <Button
        style={[AppStyle.button]}
        onPress={this.selectedSymptom.bind(this)}>
        <Text style={[AppStyle.textButton]}>{this.props.name}</Text>
      </Button>
    );
  }
}
Drawjosh
quelle