refactor: standardize event argument

This commit is contained in:
satyajit.happy
2019-08-06 17:49:18 +02:00
parent fd1c5fd0bb
commit 71f4ef1a92
4 changed files with 43 additions and 13 deletions

View File

@@ -220,6 +220,8 @@ navigation.emit({
});
```
The `data` is available under the `data` property in the `event` object, i.e. `event.data`.
The `target` property determines the screen that will receive the event. If the `target` property is omitted, the event is dispatched to all screens in the navigator.
Screens cannot emit events as there is no `emit` method on a screen's `navigation` prop.

View File

@@ -247,20 +247,23 @@ it('fires custom events', () => {
expect(secondCallback).toBeCalledTimes(0);
expect(thirdCallback).toBeCalledTimes(0);
act(() =>
act(() => {
ref.current.navigation.emit({
type: eventName,
target: ref.current.state.routes[ref.current.state.routes.length - 1].key,
data: 42,
})
);
});
});
expect(firstCallback).toBeCalledTimes(0);
expect(secondCallback).toBeCalledTimes(0);
expect(thirdCallback).toBeCalledTimes(1);
expect(thirdCallback.mock.calls[0][0]).toBe(42);
expect(thirdCallback.mock.calls[0][0].type).toBe('someSuperCoolEvent');
expect(thirdCallback.mock.calls[0][0].data).toBe(42);
act(() => ref.current.navigation.emit({ type: eventName }));
act(() => {
ref.current.navigation.emit({ type: eventName });
});
expect(firstCallback).toBeCalledTimes(1);
expect(secondCallback).toBeCalledTimes(1);

View File

@@ -160,18 +160,24 @@ export type EventMapBase = {
blur: undefined;
};
export type EventListenerCallback<Data> = Data extends undefined
? () => void
: (data: Data) => void;
export type EventArg<EventName extends string, Data> = {
readonly type: EventName;
readonly defaultPrevented: boolean;
preventDefault(): void;
} & (Data extends undefined ? {} : { readonly data: Data });
export type EventListenerCallback<EventName extends string, Data> = (
e: EventArg<EventName, Data>
) => void;
export type EventConsumer<EventMap extends { [key: string]: any }> = {
addListener<EventName extends Extract<keyof EventMap, string>>(
type: EventName,
callback: EventListenerCallback<EventMap[EventName]>
callback: EventListenerCallback<EventName, EventMap[EventName]>
): () => void;
removeListener<EventName extends Extract<keyof EventMap, string>>(
type: EventName,
callback: EventListenerCallback<EventMap[EventName]>
callback: EventListenerCallback<EventName, EventMap[EventName]>
): void;
};
@@ -180,7 +186,7 @@ export type EventEmitter<EventMap extends { [key: string]: any }> = {
type: EventName;
data?: EventMap[EventName];
target?: string;
}): void;
}): EventArg<EventName, EventMap[EventName]>;
};
class PrivateValueStore<A, B, C> {

View File

@@ -1,5 +1,5 @@
import * as React from 'react';
import { EventEmitter, EventConsumer } from './types';
import { EventEmitter, EventConsumer, EventArg } from './types';
export type NavigationEventEmitter = EventEmitter<{ [key: string]: any }> & {
create: (target: string) => EventConsumer<{ [key: string]: any }>;
@@ -51,7 +51,26 @@ export default function useEventEmitter(): NavigationEventEmitter {
? items[target] && items[target].slice()
: ([] as Listeners).concat(...Object.keys(items).map(t => items[t]));
callbacks && callbacks.forEach(cb => cb(data));
let defaultPrevented = false;
const event: EventArg<any, any> = {
get type() {
return type;
},
get data() {
return data;
},
get defaultPrevented() {
return defaultPrevented;
},
preventDefault() {
defaultPrevented = true;
},
};
callbacks && callbacks.forEach(cb => cb(event));
return event;
},
[]
);