带有React Native的EventEmitter和Subscriber ES6语法

Ada*_*ela 16 mixins eventemitter react-native

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

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

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

Tom*_*Tom 30

您不需要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 });
Run Code Online (Sandbox Code Playgroud)

完整的签名addListener需要三个args:

EventEmitter.addListener(eventName, handler, handlerContext)
Run Code Online (Sandbox Code Playgroud)

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

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 });
};
Run Code Online (Sandbox Code Playgroud)

仅供参考:我从查看臭名昭着的Subscribable mixin的明显无法实施中得到了这个.Google搜索结果基本上是Ramsay基于单一mixin的演示的回音室.

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

// 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);
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 12

这可能是一个很晚的答案,但我只是将它放在那里,供任何可能觉得这有用的人使用。

截至撰写此答案时(2020 年 7 月),React Native 自 version 以来发生了很大变化0.60.0+,您可以使用 的实例,也可以EventEmitter静态调用这些DeviceEventEmitter方法。


这是一个使用示例EventEmitter


import { EventEmitter } from 'events';

const newEvent = new EventEmitter();

// then you can use: "emit", "on", "once", and "off"
newEvent.on('example.event', () => {
  // ...
});

Run Code Online (Sandbox Code Playgroud)

使用 的另一个示例DeviceEventEmitter


import { DeviceEventEmitter } from 'react-native';

// then you can directly use: "emit", "addListener", and "removeAllListeners"
DeviceEventEmitter.emit('example.event', ['foo', 'bar', 'baz']);

Run Code Online (Sandbox Code Playgroud)

希望这对仍在寻找在 React Native 中实现自定义事件的方法的人有用。

  • DeviceEventEmitter 对我来说工作得很好,但仍然好奇为什么我找不到它的反应本机文档 (2认同)