Destekleri React.js'deki üst bileşene aktarma


296

propsReact.js'de bir çocuğun olaylarını kullanarak ebeveynine geçmesinin basit bir yolu yok mu?

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

Bir girişin değerini geçmek için kontrollü bileşenler kullanabileceğinizi biliyorum, ancak tüm kit n 'kaboodle'ı geçmek güzel olurdu. Bazen alt bileşen, aramak istemeyeceğiniz bir dizi bilgi içerir.

Belki de bileşeni etkinliğe bağlamanın bir yolu var mı?

GÜNCELLEME - 9/1/2015

React'i bir yılı aşkın bir süredir kullandıktan ve Sebastien Lorber'in cevabı tarafından teşvik edildikten sonra, çocuk bileşenlerini ebeveynlerdeki işlevlere argüman olarak aktarmanın aslında React yolu olmadığı veya iyi bir fikir olmadığı sonucuna vardım . Cevabı değiştirdim.


Benzer sorunlara ( burada ve burada ) çeşitli cevaplar var , ancak bunların hiçbiri özellikle zarif görünmüyor
Bojangles

Katılıyorum - olayları zincirden geçirmek harika, ancak hangi bileşenin olaydan kaynaklandığından emin olmak harika olurdu.
KendallB

Lütfen cevaplarıma bir göz atın, çünkü kabul edilen cevap yeterince iyi değil; stackoverflow.com/a/31756470/82609
Sebastien Lorber

1
kit n 'kaboodle - Her şeyi dahil etmek için. Tüm çan ve ıslık almak için. Combonation. urbandictionary.com/define.php?term=kit%20and%20caboodle
Filip Bartuzi

Yanıtlar:


269

Düzenleme : ES6 güncelleştirilmiş örnekleri için son örneklere bakın.

Bu cevap, doğrudan ebeveyn-çocuk ilişkisi konusunu ele alır. Ebeveyn ve çocuk potansiyel olarak çok sayıda aracıya sahip olduğunda, bu yanıtı kontrol edin .

Diğer çözümlerin amacı eksik

Hala iyi çalışıyorken, diğer cevaplarda çok önemli bir şey eksik.

React.js'de bir çocuğun desteklerini olayları kullanarak ebeveynine iletmenin basit bir yolu yok mu?

Ebeveyn zaten bu çocuk pervane var! : Çocuğun bir pervane varsa, bunun nedeni ebeveyninin çocuğa pervane sağlamasıdır! Ebeveynin zaten bu pervane olduğu halde, çocuğun pervaneyi ebeveyne geri iletmesini neden istiyorsun?

Daha iyi uygulama

Çocuk : Gerçekten bundan daha karmaşık olması gerekmez.

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

Bekar çocuklu ebeveyn : çocuğa geçtiği değeri kullanarak

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

Çocuk listesiyle birlikte ebeveyn : hala ebeveyn üzerinde ihtiyacınız olan her şeye sahipsiniz ve çocuğu daha karmaşık hale getirmenize gerek yok.

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

Kullanmak this.handleChildClick.bind(null,childIndex)ve sonra kullanmak da mümkündürthis.state.childrenData[childIndex]

Bir nullbağlamla bağlandığımızı unutmayın, aksi halde React otomatik tarama sistemi ile ilgili bir uyarı yayınlar . Null kullanılması, işlev bağlamını değiştirmek istemediğiniz anlamına gelir. Ayrıca bakınız .

Diğer cevaplardaki kapsülleme ve kuplaj hakkında

Bu benim için eşleştirme ve kapsülleme açısından kötü bir fikir:

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

Destekleri kullanma : Yukarıda açıkladığım gibi, zaten ebeveynte desteklere sahipsiniz, bu nedenle desteklere erişmek için tüm alt öğeyi geçmek işe yaramaz.

Refs kullanma : Etkinlikte zaten tıklama hedefiniz var ve çoğu durumda bu yeterli. Ek olarak, doğrudan çocuk üzerinde bir ref kullanmış olabilirsiniz:

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

Ve üst öğedeki DOM düğümüne

React.findDOMNode(this.refs.theChild)

Ebeveynteki çocuğun birden fazla referansına erişmek istediğiniz daha gelişmiş durumlarda, çocuk tüm dom düğümlerini doğrudan geri çağrıda geçirebilir.

Bileşenin bir arayüzü (sahne) vardır ve ebeveyn, iç DOM yapısı veya hangi DOM düğümlerini başvurduğunu beyan ettiği de dahil olmak üzere çocuğun iç çalışması hakkında hiçbir şey varsaymamalıdır. Çocuğun ref'sini kullanan bir ebeveyn, 2 bileşeni sıkıca bağladığınız anlamına gelir.

Sorunu göstermek için, tarayıcıların içinde kaydırıcılar, kaydırma çubukları, video oynatıcılar gibi şeyler oluşturmak için kullanılan Shadow DOM ile ilgili bu alıntıyı alacağım ...:

Sizin, Web geliştiricisinin erişebildikleri ve uygulama ayrıntıları olarak kabul edilenler arasında bir sınır oluşturdular, böylece sizin için erişilemezler. Ancak tarayıcı, bu sınırın ötesinde tuzağa düşebilir. Bu sınır uygulandığında, tıpkı sizin yaptığınız gibi div ve yayılma alanlarından aynı eski Web teknolojilerini kullanarak tüm HTML öğelerini oluşturabildiler.

Sorun, çocuk uygulama ayrıntılarının ebeveyne sızmasına izin verirseniz, ebeveynleri etkilemeden çocuğu yeniden düzenlemeyi çok zorlaştırmanızdır. Bu, bir kütüphane yazarı (veya Shadow DOM'lu bir tarayıcı düzenleyicisi olarak) anlamına gelir, çünkü bu çok tehlikelidir, çünkü istemcinin çok fazla erişmesine izin verirsiniz ve geriye dönük uyumluluğu bozmadan kodu yükseltmeyi çok zorlaştırırsınız.

Chrome, kaydırma çubuğunu uyguladığında, istemcinin bu kaydırma çubuğunun iç dom düğümlerine erişmesine izin verdiyse, bu, istemcinin bu kaydırma çubuğunu kırma olasılığına sahip olabileceği ve Chrome'u, kaydırma çubuğu ... Bunun yerine, kaydırma çubuğunun bazı bölümlerini CSS ile özelleştirme gibi bazı güvenli şeylere erişim sağlarlar.

Başka bir şey kullanma hakkında

Tüm bileşeni geri aramada geçirmek tehlikelidir ve acemi geliştiricilerin ebeveynin içinde arama childComponent.setState(...)veya childComponent.forceUpdate()yeni değişkenler atama gibi çok garip şeyler yapmalarına yol açabilir ve tüm uygulamayı akla zorlaştırır.


Düzenle: ES6 örnekleri

Birçok kişi artık ES6 kullandığından, ES6 sözdizimi için aynı örnekler

Çocuk çok basit olabilir:

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

Ebeveyn bir sınıf olabilir (ve sonunda devletin kendisini yönetebilir, ancak burada sahne olarak geçiyorum:

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

Ancak, durumu yönetmesi gerekmiyorsa da basitleştirilebilir:

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 UYARISI (ES5 / ES6 için geçerlidir): PureComponentveya shouldComponentUpdatekullanıyorsanız onClick={e => doSomething()}, üst oluşturma her oluşturulduğunda yeni bir işlev oluşturacağından, oluşturma işlemi sırasında doğrudan bağlama veya bağlama nedeniyle yukarıdaki uygulamalar varsayılan olarak optimize edilmez . Bu, uygulamanızda mükemmel bir darboğaz varsa, verileri çocuklara aktarabilir ve optimizasyonun başlayabilmesi için "kararlı" geri arama (üst sınıfta ayarlanır ve thissınıf yapıcısına bağlanır ) içinde yeniden enjekte PureComponentedebilirsiniz. kendiniz uygulayabilir shouldComponentUpdateve sahne karşılaştırma karşılaştırmasında geri aramayı yoksayabilirsiniz.

İnce ayarlı optimizasyonlar elde etmek için daha yüksek dereceli bileşenler sağlayan Yeniden Oluşturma kitaplığını da kullanabilirsiniz :

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

Bu durumda, Child bileşenini aşağıdakileri kullanarak optimize edebilirsiniz:

const OptimizedChild = onlyUpdateForKeys(['text'])(Child)

1
Evet, geçen yılı React kullanarak geçirdim, katılıyorum - somutlaştırılmış bileşenleri işlevler aracılığıyla iletmek için iyi bir neden yok. Kendi cevabımı reddedeceğim. Ayrıca, belki de bazı değişikliklerle cevabı değiştirmeye hazırım: "Daha iyi uygulama", bu sorunun ortaya çıkmasının asıl nedenine değinmiyor, "Çocuklarımdan hangisinin bir grup arasında seçildiğini nasıl bilebilirim?" Flux, herhangi bir iyi boyutlu uygulamanın cevabıdır, ancak küçük uygulamalarda, bir fonksiyon aracılığıyla çağrı zincirini (bileşenleri değil) değerleri iletmek güzel props. Katılıyorum?
KendallB

@KendallB cevabımı kabul ettiğine sevindim :) How do I know which of my children was chosen among a group?Bu gerçekten orijinal sorunun bir parçası değil, ama cevabımı çözümü dahil ettim. Düzenlemenizin aksine, bir listeyle uğraşırken bile binddoğrudan üst öğede kullanabileceğiniz için çocuğu değiştirmenin gerekli olmadığını düşünüyorum .
Sebastien Lorber

Cevabınız için bir düzenleme yaptım, refs ile ilgili kısım. omerwazir.com/posts/react-getdomnode-replaced-with-findDOMNode
ffxsam

Merhaba @SebastienLorber Gelecekten geliyorum. Otomatik taramaonClick={this.handleChildClick.bind(null,childData)} hakkında bahsettiğiniz bu satırla ilgili olarak React'ın sınıf modeline dahil edilmediği için bu hala geçerli mi ? Bir çok şey okudum ama bu kısım beni hala karıştırıyor. Ben ES6 kullanıyorum class modeldeğiştiğimi arada nulletmek thisve benim kod hala iş gibi görünüyor. Kodunuzun bu bölümünü nasıl ES6 stiline çevirirsiniz?
JohnnyQ

Ayrıca bunu en son React'te çalıştırmak için uğraşıyorum, neyin değişmesi gerekiyor?
Hüseyin Duvigneau

143

Güncelleme (9/1/15): OP bu soruyu biraz hareketli bir hedef haline getirdi. Tekrar güncellendi. Cevabımı güncellemekten kendimi sorumlu hissediyorum.

İlk olarak, verilen örneğinize bir cevap:

Evet, bu mümkün.

Bunu, Çocuğu şu onClickşekilde güncelleyerek çözebilirsiniz this.props.onClick.bind(null, this):

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

Üst öğenizdeki olay işleyicisi, bileşene ve olaya şu şekilde erişebilir:

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

JSBin anlık görüntüsü


Ama sorunun kendisi yanıltıcı

Ebeveyn zaten Çocukları bilir props.

Bu, sağlanan örnekte net değildir, çünkü aslında hiçbir sahne sağlanmamıştır. Bu örnek kod, sorulan soruyu daha iyi destekleyebilir:

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

Bu örnekte, Çocuk aksesuarlarının ne olduğunu zaten bildiğiniz açıktır.

JSBin anlık görüntüsü


Eğer gerçekten bir çocuğun aksesuarlarını kullanmakla ilgiliyse ...

Eğer gerçekten bir çocuğun aksesuarlarını kullanmakla ilgiliyse, Çocuk'la bağlantı kurmayı tamamen önleyebilirsiniz.

JSX, Child gibi bileşenlerde sıklıkla kullandığım bir yayılım özniteliklerine sahiptir . Hepsini alır propsve bir bileşene uygular. Çocuk şöyle görünecektir:

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

Değerleri doğrudan Üst Öğede kullanmanıza izin verme:

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 anlık görüntüsü


Ek Alt bileşenleri bağladığınız için başka bir yapılandırma gerekmez

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 anlık görüntüsü

Ama bunun gerçek kullanım durumunuz olmadığını sanıyorum. Öyleyse biraz daha kazalım…


Sağlam pratik bir örnek

Verilen örneğin genel doğası hakkında konuşmak zor. Yukarıdaki soru için çok Reacty yöntemiyle uygulanan pratik bir kullanım gösteren bir bileşen oluşturdum :

DTServiceCalculator çalışma örneği
DTServiceCalculator repo

Bu bileşen basit bir servis hesap makinesidir. Buna bir hizmet listesi (adlar ve fiyatlar ile birlikte) sağlarsınız ve toplam seçilen fiyatları hesaplar.

Çocuklar mutlu bir şekilde cahil

ServiceItembu örnekteki alt öğedir. Dış dünya hakkında pek bir fikri yok. Biri tıklandığında çağrılacak bir işlev olan birkaç sahne gerektirir .

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

handleClickSağlanan index[ kaynak ] ile sağlanan geri arama çağırmak için başka bir şey yapmaz .

Ebeveynler Çocuktur

DTServicesCalculatorüst bileşen bu örnektir. Aynı zamanda bir çocuk. Haydi bakalım.

DTServiceCalculatoralt bileşenlerin bir listesini oluşturur ServiceItemve onlara sahne kaynağı [ kaynak ] sağlar. Bu üst bileşen ServiceItemama listeden geçen bileşenin alt bileşenidir. Verilere sahip değil. Böylece, bileşenin işlenmesini üst bileşen kaynağına devreder

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

handleServiceItemçocuktan geçirilen dizini yakalar ve üst [ kaynak ] sağlar

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

Sahipler her şeyi biliyor

“Mülkiyet” kavramı React'te önemli bir kavramdır. Burada daha fazla bilgi almanızı tavsiye ederim .

Gösterdiğim örnekte, durumun sahibi olan bileşene ulaşıncaya kadar bir olayın bileşen ağacında işlenmesine yetki vermeye devam ediyorum.

Biz nihayet oraya, biz böyle [ kaynak ] gibi devlet seçimi / seçimini ele :

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


Sonuç

En dıştaki bileşenlerinizi mümkün olduğunca opak tutmaya çalışın. Bir üst bileşenin bunları uygulamayı nasıl seçebileceği konusunda çok az tercihleri ​​olduğundan emin olmaya çalışın.

İşlediğiniz verilere kimin sahip olduğunun farkında olun. Çoğu durumda, ağacı işleyen olayı , bu duruma sahip olan bileşene devretmeniz gerekir .

Kenara: Akı deseni , uygulamalarda bu tür gerekli bağlantıyı azaltmanın iyi bir yoludur.


Kısa cevap için teşekkürler, React'i biraz daha iyi anlamama yardımcı oldu! Aynı satırlar boyunca bir sorum var. Pub / sub için Flux kullanıyorum. Child olay işleyicisini örneğiniz gibi Ebeveyne iletmek yerine, bunu bir 'eylem' olarak uygulamak ve dinlemek mümkündür. Bunu Flux'un iyi bir alternatifi ve kullanımı olarak düşünür müsünüz?
Pathsofdesign

1
Teşekkürler @Pathsofdesign! Bağlıdır. Flux, bu Controller-Views kavramına sahiptir. Bu örnekte, sadece bir aptal görünüm (bileşen) Parentvarken Child, böyle bir Controller-View olabilir . Yalnızca Denetleyici-Görünümler uygulama hakkında bilgi sahibi olmalıdır. Bu durumda, yine Eylem'i geçerdi Parentiçin Childfigüran olarak. Eylem'in kendisi söz konusu olduğunda, Flux, Görünümleri güncellemek için Eylemler arasında etkileşim için güçlü bir şekilde reçete edilmiş bir desene sahiptir. facebook.github.io/flux/docs/…
chantastic

1
onClick={this.onClick.bind(null, this.state.text)}ebeveynin buna sahip olduğu için durumu bağlamaya gerek yoktur. sadece onClick={this.onClick}işe yarayacak. Nerede onClick = ()=>{const text = this.state.text;..}ebeveyn
Shishir Arora

25

Basit bir cevap var gibi görünüyor. Bunu düşün:

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

Anahtar çağırıyor bind(null, this)üzerinde this.props.onClickebeveynden geçti olay. Şimdi, onClick işlevi componentAND değişkenlerini kabul eder event. Bence bu tüm dünyaların en iyisi.

GÜNCELLEME: 9/1/2015

Bu kötü bir fikirdi: Çocuk uygulama detaylarının ebeveyne sızmasına izin vermek asla iyi bir yol değildi. Sebastien Lorber'in cevabına bakınız.


argümanlar yanlış bir şekilde değil mi (takas yerler)?
Surrican

1
@TheSurrican Hayır, gayet iyi. İlk argüman thisişlev içinde (zaten gerekli değildir) bağlıdır ve ikincisi onClick çağrıldığında ilk argüman olarak eklenir.
manmal

13

Soru, argümanın çocuktan üst bileşene nasıl geçirileceğidir. Bu örneğin kullanımı ve test edilmesi kolaydır:

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

JSFIDDLE'a bak


Benim durumumda geri arama işlevini click () 'e
Long Nguyen

6

Temel olarak Çocuk ve Ebeveyn'e bilgi ve ebeveyn göndermek için sahne donanımı kullanırsınız.

Tüm harika cevaplara ek olarak, React'ta çocuktan üst bileşene geçiş değerlerini açıklayan basit bir örnek vereyim

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'));

Bu, şimdi istemcinizden sunucuya değerler iletebilirsiniz.

Header.js'deki Değiştir işlevine göz atın

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

Değerleri istemciden sunucuya desteklere bu şekilde aktarırsınız



2

Burada, üst yapıcıdaki fonksiyon bağlamayı kullanan basit bir 3 aşamalı ES6 uygulaması bulunmaktadır. Bu, resmi tepki eğitiminin önerdiği ilk yoldur (burada ele alınmayan genel sınıf alanları sözdizimi de vardır). Tüm bu bilgileri burada bulabilirsiniz https://reactjs.org/docs/handling-events.html

Ebeveyn İşlevlerini Çocukların Çağırması İçin Bağlama (Ve verileri ebeveyne aktarma: D)

  1. Üst yapıcıda, üst öğede oluşturduğunuz işlevi bağladığınızdan emin olun
  2. Bağlı işlevi çocuğa pervane olarak geçirin (lambda yok çünkü işlev için bir ref geçiyoruz)
  3. Bir alt olaydan ilişkili işlevi çağırın (Lambda! Olay tetiklendiğinde işlevi çağırırız. Bunu yapmazsak, işlev otomatik olarak yükte çalışır ve olayda tetiklenmez.)

Ebeveyn İşlevi

handleFilterApply(filterVals){} 

Veli Oluşturucu

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

Pervane Çocuklara Geçti

onApplyClick = {this.handleFilterApply}

Çocuk Olay Çağrısı

onClick = {() => {props.onApplyClick(filterVals)}

0

Bu, onClick olayını kullanmadan bir örnektir. Ben sadece sahne tarafından çocuğa bir geri arama fonksiyonu geçiriyorum. Bu geri arama ile çocuk çağrısı da veriyi geri gönderir. Dokümanlardaki örneklerden ilham aldım .

Küçük örnek (bu bir tsx dosyalarında, bu yüzden sahne ve durumların tam olarak bildirilmesi gerekir, bileşenlerden bazı mantığı sildim, bu yüzden daha az kod).

* Güncelleme: Önemli, geri aramaya bağlamaktır, aksi takdirde geri arama, üst öğeye değil çocuğun kapsamına sahiptir. Tek sorun: "eski" ebeveyn ...

SymptomChoser üst öğedir:

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

Belirti çocuktur (çocuğun geri arama işlevini bildirdiğim desteklerinde, seçilen işlevde Geri arama çağrılır):

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>
    );
  }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.