@@ -5,6 +5,10 @@ export interface IEventQueue {
5
5
[ _ : string ] : ( ( ) => void ) [ ] ;
6
6
}
7
7
8
+ export interface IActionAddPayload {
9
+ eventName : string ;
10
+ handlers : ( ( ) => void ) [ ] ;
11
+ }
8
12
export interface IState {
9
13
eventQueue : IEventQueue ;
10
14
eventNameQueue : string [ ] ;
@@ -21,7 +25,7 @@ export enum IActionType {
21
25
22
26
export interface IAction {
23
27
type : IActionType ;
24
- payload : string | string [ ] | null ;
28
+ payload : string | string [ ] | IActionAddPayload | null ;
25
29
}
26
30
27
31
export const safeNamespace = [ '__taro' , 'at' ] ;
@@ -34,7 +38,24 @@ const initState: IState = {
34
38
function useEvent ( namespace : string ) {
35
39
const { eventBus } = useContext ( context ) ;
36
40
37
- const setListener = useCallback ( ( ) => { } , [ ] ) ;
41
+ const setListener = useCallback (
42
+ ( eventName : string , ...handlers : ( ( ) => void ) [ ] ) => {
43
+ if ( ! eventName || safeNamespace . some ( ( v ) => eventName . startsWith ( v ) ) ) {
44
+ console . warn ( 'eventName not valid. listen failed' ) ;
45
+ } else if ( ! handlers . length ) {
46
+ console . warn ( 'you mast provide one handler to listen. add failed' ) ;
47
+ } else {
48
+ dispatch ( {
49
+ type : IActionType . ADD ,
50
+ payload : {
51
+ eventName,
52
+ handlers,
53
+ } ,
54
+ } ) ;
55
+ }
56
+ } ,
57
+ [ ] ,
58
+ ) ;
38
59
39
60
const removeListener = useCallback ( ( ) => { } , [ ] ) ;
40
61
@@ -66,20 +87,77 @@ function useEvent(namespace: string) {
66
87
}
67
88
} , [ ] ) ;
68
89
69
- const safeRemoveEvents = useCallback ( ( ) => { } , [ ] ) ;
90
+ const safeRemoveEvents = useCallback (
91
+ ( eventNameQueue : string [ ] , eventQueue ) : IEventQueue => {
92
+ const removeEventName = eventNameQueue . filter (
93
+ ( v ) => ! safeNamespace . some ( ( n ) => v . startsWith ( n ) ) ,
94
+ ) ;
95
+
96
+ removeEventName . forEach ( ( v ) => eventBus . off ( v ) ) ;
97
+ const offQueue : IEventQueue = { } ;
98
+ if ( eventNameQueue . length === 1 && removeEventName . length ) {
99
+ Object . keys ( eventQueue ) . forEach ( ( key ) => {
100
+ if ( ! eventNameQueue . includes ( key ) ) {
101
+ offQueue [ key ] = eventQueue [ key ] ;
102
+ }
103
+ } ) ;
104
+ }
105
+ return offQueue ;
106
+ } ,
107
+ [ ] ,
108
+ ) ;
70
109
71
110
const reducer = useCallback (
72
111
( state : IState , { type, payload } : IAction ) : IState => {
73
112
switch ( type ) {
74
113
case IActionType . CLEAR :
75
114
if ( ! payload ) {
76
- eventBus . off ( ) ;
115
+ safeRemoveEvents ( state . eventNameQueue , state . eventQueue ) ;
116
+ return {
117
+ eventQueue : { } ,
118
+ eventNameQueue : eventBus . display ( ) ,
119
+ } ;
120
+ } else {
121
+ return {
122
+ eventNameQueue : state . eventNameQueue . filter ( ( v ) => v !== payload ) ,
123
+ eventQueue : safeRemoveEvents (
124
+ [ payload as string ] ,
125
+ state . eventQueue ,
126
+ ) ,
127
+ } ;
128
+ }
129
+ case IActionType . ADD :
130
+ if (
131
+ ! payload ||
132
+ ! ( payload as IActionAddPayload ) . eventName ||
133
+ ! ( payload as IActionAddPayload ) . handlers
134
+ ) {
135
+ console . warn (
136
+ 'you mast provider eventName and one handler to listen' ,
137
+ ) ;
138
+ return {
139
+ ...state ,
140
+ } ;
77
141
} else {
78
- eventBus . off ( payload as string ) ;
142
+ ( payload as IActionAddPayload ) . handlers . forEach ( ( handler ) => {
143
+ eventBus . on ( ( payload as IActionAddPayload ) . eventName , handler ) ;
144
+ } ) ;
145
+ return {
146
+ eventNameQueue : [
147
+ ...new Set ( [
148
+ ...state . eventNameQueue ,
149
+ ( payload as IActionAddPayload ) . eventName ,
150
+ ] ) ,
151
+ ] ,
152
+ eventQueue : {
153
+ ...state . eventQueue ,
154
+ [ ( payload as IActionAddPayload ) . eventName ] : [
155
+ ...state . eventQueue [ ( payload as IActionAddPayload ) . eventName ] ,
156
+ ...( payload as IActionAddPayload ) . handlers ,
157
+ ] ,
158
+ } ,
159
+ } ;
79
160
}
80
- return {
81
- ...state ,
82
- } ;
83
161
default :
84
162
return state ;
85
163
}
0 commit comments