### Events (for UI components)

Keep in mind:
- Events share namespace (so come up with an app-wide naming convention)

#### React

```js
// VideoPlayer.js

class VideoPlayer extends React.PureComponent {
  _onEnd = (event) => {
    if (!this.props.onEnd) {
      return;
    }
    this.props.onEnd(event.nativeEvent)
  }
  render() {
    // Re-assign onEnd to the private _onEnd and store it in `nativeProps`
    const nativeProps = {
      ...this.props,
      onEnd: this._onEnd,
    }
    return (
      <RCTVideo
        {...nativeProps}
      />
    )
  }
}

const RCTVideo = requireNativeComponent('RCTVideo', VideoPlayer)

VideoPlayer.propTypes = {
  /**
   *  Callback that is called when the current player item ends.
   */
  onEnd: PropTypes.func,
}
```

#### iOS

[docs](https://facebook.github.io/react-native/docs/native-components-ios.html#events)

> Notes: 
> Bubbling events are like DOM events so that a parent component can capture an event fired by its child. Generally these are UI-related, like "the user touched this box". Direct events are not bubbled and are intended for more abstract events like "this image failed to load".

```obj-c
// VideoPlayer.h
#import <UIKit/UIKit.h>
#import <React/RCTView.h>

@interface VideoPlayer : UIView

// or RCTBubblingEventBlock
@property (nonatomic, copy) RCTDirectEventBlock onEnd;

@end

// VideoPlayerManager.m (inherits from RCTViewManager)
@implementation VideoPlayerManager

RCT_EXPORT_MODULE()

RCT_EXPORT_VIEW_PROPERTY(onEnd, RCTDirectEventBlock)

- (UIView *)view
{
  ...
}

/* 
 * `VideoPlayerManager` acts as the delegate of all of the `VideoPlayer` views. This is just one
 * pattern and it's perfectly fine to call `onEnd` from the `VideoPlayer` directly.
 */
- (void)onEnd:(VideoPlayer *)videoPlayer
{
  if (!videoPlayer.onEnd) {
    return;
  }
  videoPlayer.onEnd(@{ @"some-data" : @1 });
}

@end
```

#### Android

[docs](https://facebook.github.io/react-native/docs/native-components-android.html#events)

[example](http://stackoverflow.com/a/34740528/598993)

Define a custom event mapping by overriding `getExportedCustomDirectEventTypeConstants` in the 
manager class:

```java
// VideoPlayerManager.java
@Override
public @Nullable Map getExportedCustomDirectEventTypeConstants() {
    return MapBuilder.of(
            "onEnd",
            MapBuilder.of("registrationName", "onEnd")
    );
}
```

Dispatch the event:

```java
// VideoPlayerView.java
private void dispatchOnEnd() {
  WritableMap event = Arguments.createMap();
  ...
  reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
    getId(),
    "onEnd",
    event
  );
}
```

[__Go to Top__](https://gist.github.com/chourobin/f83f3b3a6fd2053fad29fff69524f91c#file-0-bridging-react-native-cheatsheet-md)