2016-04-21 18 views
12

Sto tentando di implementare una relazione EventEmitter/Subscriber tra due componenti in una classe nativa reattiva. Ho visto riferimento i seguenti materiali:EventEmitter e Subscriber ES6 Sintassi con React Native

Queste soluzioni sono adeguate per quello che sto cercando di realizzare, tuttavia, essi si preoccupano richiedere l'uso di mixins: [Subscribable.Mixin] sulla componente di ricezione funzionare correttamente con Subscriber. Sfortunatamente, sto usando ES6 e estendo le mie lezioni da Component quindi non posso usare questa sintassi mixin.

La mia domanda è: come posso implementare le soluzioni di cui sopra in ES6 senza l'uso di mixin?

+0

Qui qualcuno suggerisce di utilizzare semplicemente utilizzare il "vecchio modo" di scrivere componente: http://hi-tips.tumblr.com/post/137014836571/use-eventemitter-for-calling-child-component -event Ho lo stesso problema e vorrei sapere se c'è un modo corretto di farlo in ES6 –

+0

Sto ancora cercando questo. Sono riluttante ad iniziare a usare 'react-mixin'. – Tom

risposta

19

Non è necessario mixins utilizzare EventEmitters.

semplice demo:

import EventEmitter from 'EventEmitter'; 

let x = new EventEmitter(); 

function handler(arg) { 
    console.log(`event-name has occurred! here is the event data arg=${JSON.stringify(arg)}`); 
} 

x.addListener('event-name', handler); 

x.emit('event-name', { es6rules: true, mixinsAreLame: true }); 

La firma completa per addListener prende tre argomenti:

EventEmitter.addListener(eventName, handler, handlerContext) 

In un componente di reagire, è probabile che desidera utilizzare che arg contesto, in modo che il gestore possa essere un metodo di classe invece di una funzione inline e conserva ancora this == component instance. Es .:

componentDidMount() { 
    someEmitter.addListener('awesome', this.handleAwesomeEvents, this); 
    // the generalist suggests the alternative: 
    someEmitter.addListener('awesome', this.handleAwesomeEvents.bind(this)); 
} 

handleAwesomeEvents = (event) => { 
    let awesomeness = event.awesomeRating; 

    // if you don't provide context in didMount, 
    // "this" will not refer to the component, 
    // and this next line will throw 
    this.setState({ awesomeness }); 
}; 

FYI: Ho ricevuto questo da guardando l'attuazione decisamente unmagical di the infamous Subscribable mixin. I risultati di ricerca di Google sono fondamentalmente una camera di eco della demo su singolo mixin di Ramsay.

P.S. Per quanto riguarda l'esposizione di questo emettitore a un altro componente, probabilmente il componente proprietario fornisce una funzione per ricevere il riferimento dell'emettitore e il componente che crea l'emettitore eseguirà quindi quel puntello con l'emettitore in modo condizionale.

// owner's render method: 
<ThingThatEmits 
    onEmitterReady={(emitter) => this.thingEmitter = emitter} 
/> 

// inside ThingThatEmits: 
componentDidMount() { 
    this.emitter = new EventEmitter(); 

    if(typeof this.props.onEmitterReady === 'function') { 
     this.props.onEmitterReady(this.emitter); 
    } 
} 
+1

grazie! la tua "Demo semplice" era esattamente ciò che dovevo vedere per fare clic. – iksnae

+0

Ciao Tom, quando provo a chiamare 'let test = new EventEmitter();' getta 'undefined non è un costruttore (valutando 'new _reactNative.EventEmitter()')' qualche pensiero su questo? – Richard

+0

@Richard: Nessuno. Quale versione di react-native stai usando? Sei sicuro di aver importato correttamente? Hai provato a riavviare il tuo packager RN? Si tratta di un errore di build-time o di runtime? – Tom

1

Sono riuscito a ottenere una soluzione con react-mixin. Non sei sicuro di come sia corretto, ma funziona senza alcuna modifica. La chiave sta aggiungendo reactMixin(DetailView.prototype, Subscribable.Mixin); dopo la definizione della classe.

Andando fuori l'esempio che fluttua intorno per EventEmitter e sottoscrivibile:

'use strict'; 

var reactMixin = require('react-mixin'); 
var React = require('react-native'); 
var EventEmitter = require('EventEmitter'); 
var Subscribable = require('Subscribable'); 

var { 
    AppRegistry, 
    StyleSheet, 
    Text, 
    View, 
    NavigatorIOS 
} = React; 

class MainView extends Component { 
    constructor(props){ 
     super(props); 
     this.EventEmitter = new EventEmitter(); 
    } 

    somethingHappenedFunction(){ 
     this.EventEmitter.emit("update_event", { message: "hello from up here"}); 
    } 

    //rest of the class 
} 

class DetailView extends Component { 
    componentDidMount(){ 
    this.addListenerOn(this.props.events, 'update_event', this.miscFunction); 
    } 

    miscFunction(args) { 
    console.log("message: %s", args.message); 
    } 

    //rest of the class 
} 
reactMixin(DetailView.prototype, Subscribable.Mixin);