mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-04-29 12:55:21 +08:00
refactor: standardize event argument
This commit is contained in:
@@ -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.
|
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.
|
Screens cannot emit events as there is no `emit` method on a screen's `navigation` prop.
|
||||||
|
|||||||
@@ -247,20 +247,23 @@ it('fires custom events', () => {
|
|||||||
expect(secondCallback).toBeCalledTimes(0);
|
expect(secondCallback).toBeCalledTimes(0);
|
||||||
expect(thirdCallback).toBeCalledTimes(0);
|
expect(thirdCallback).toBeCalledTimes(0);
|
||||||
|
|
||||||
act(() =>
|
act(() => {
|
||||||
ref.current.navigation.emit({
|
ref.current.navigation.emit({
|
||||||
type: eventName,
|
type: eventName,
|
||||||
target: ref.current.state.routes[ref.current.state.routes.length - 1].key,
|
target: ref.current.state.routes[ref.current.state.routes.length - 1].key,
|
||||||
data: 42,
|
data: 42,
|
||||||
})
|
});
|
||||||
);
|
});
|
||||||
|
|
||||||
expect(firstCallback).toBeCalledTimes(0);
|
expect(firstCallback).toBeCalledTimes(0);
|
||||||
expect(secondCallback).toBeCalledTimes(0);
|
expect(secondCallback).toBeCalledTimes(0);
|
||||||
expect(thirdCallback).toBeCalledTimes(1);
|
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(firstCallback).toBeCalledTimes(1);
|
||||||
expect(secondCallback).toBeCalledTimes(1);
|
expect(secondCallback).toBeCalledTimes(1);
|
||||||
|
|||||||
@@ -160,18 +160,24 @@ export type EventMapBase = {
|
|||||||
blur: undefined;
|
blur: undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type EventListenerCallback<Data> = Data extends undefined
|
export type EventArg<EventName extends string, Data> = {
|
||||||
? () => void
|
readonly type: EventName;
|
||||||
: (data: Data) => void;
|
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 }> = {
|
export type EventConsumer<EventMap extends { [key: string]: any }> = {
|
||||||
addListener<EventName extends Extract<keyof EventMap, string>>(
|
addListener<EventName extends Extract<keyof EventMap, string>>(
|
||||||
type: EventName,
|
type: EventName,
|
||||||
callback: EventListenerCallback<EventMap[EventName]>
|
callback: EventListenerCallback<EventName, EventMap[EventName]>
|
||||||
): () => void;
|
): () => void;
|
||||||
removeListener<EventName extends Extract<keyof EventMap, string>>(
|
removeListener<EventName extends Extract<keyof EventMap, string>>(
|
||||||
type: EventName,
|
type: EventName,
|
||||||
callback: EventListenerCallback<EventMap[EventName]>
|
callback: EventListenerCallback<EventName, EventMap[EventName]>
|
||||||
): void;
|
): void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -180,7 +186,7 @@ export type EventEmitter<EventMap extends { [key: string]: any }> = {
|
|||||||
type: EventName;
|
type: EventName;
|
||||||
data?: EventMap[EventName];
|
data?: EventMap[EventName];
|
||||||
target?: string;
|
target?: string;
|
||||||
}): void;
|
}): EventArg<EventName, EventMap[EventName]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PrivateValueStore<A, B, C> {
|
class PrivateValueStore<A, B, C> {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { EventEmitter, EventConsumer } from './types';
|
import { EventEmitter, EventConsumer, EventArg } from './types';
|
||||||
|
|
||||||
export type NavigationEventEmitter = EventEmitter<{ [key: string]: any }> & {
|
export type NavigationEventEmitter = EventEmitter<{ [key: string]: any }> & {
|
||||||
create: (target: string) => EventConsumer<{ [key: string]: any }>;
|
create: (target: string) => EventConsumer<{ [key: string]: any }>;
|
||||||
@@ -51,7 +51,26 @@ export default function useEventEmitter(): NavigationEventEmitter {
|
|||||||
? items[target] && items[target].slice()
|
? items[target] && items[target].slice()
|
||||||
: ([] as Listeners).concat(...Object.keys(items).map(t => items[t]));
|
: ([] 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;
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user