带有React Native的EventEmitter和Subscriber ES6语法

时间:2016-04-21 15:44:50

标签: react-native mixins eventemitter

我正在尝试在react本机类中的两个组件之间实现EventEmitter / Subscriber关系。我见过参考以下材料:

这些解决方案足以满足我的目标,但是,他们需要在接收组件上使用mixins: [Subscribable.Mixin]才能与Subscriber一起正常使用。不幸的是,我正在使用ES6并从Component扩展我的类,所以我不能使用这个mixin语法。

我的问题是:如何在不使用mixins的情况下在ES6中实现上述解决方案?

3 个答案:

答案 0 :(得分:27)

您不需要mixins来使用EventEmitters。

简单演示:

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

addListener的完整签名需要三个参数:

EventEmitter.addListener(eventName, handler, handlerContext)

在react组件中,您可能希望使用该上下文arg,以便处理程序可以是类方法而不是内联函数,并且仍然保留this == component instance。 E.g:

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

仅供参考:我从the infamous Subscribable mixin的明显无法实现的实施中得到了这一点。谷歌搜索结果基本上是拉姆齐基于单一mixin的演示的回音室。

P.S。至于将这个发射器暴露给另一个组件,我可能让拥有组件提供接收发射器参考的功能,然后创建发射器的组件将有条件地用发射器执行该支柱。

// 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 :(得分:7)

这可能是一个很晚的答案,但是我将它发布给那些可能会觉得有用的人。

截至撰写此答案之时(2020年7月),自版本0.60.0+起,React Native发生了很大变化,您可以使用EventEmitter的实例,也可以静态调用{{ 1}}方法。


以下是使用DeviceEventEmitter的示例:

EventEmitter

另一个使用 import { EventEmitter } from 'events'; const newEvent = new EventEmitter(); // then you can use: "emit", "on", "once", and "off" newEvent.on('example.event', () => { // ... }); 的示例:

DeviceEventEmitter

希望对于仍在React Native中实现自定义事件的人来说都很方便。

答案 2 :(得分:1)

我能够通过react-mixin获得解决方法。不确定它是多么合适,但它没有任何修改。关键是在类定义之后添加reactMixin(DetailView.prototype, Subscribable.Mixin);

关闭为EventEmitter和Subscribable浮动的示例:

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