1
- import { update , isFn , getCurrentFiber } from " ./reconcile"
1
+ import { update , isFn , getCurrentFiber } from ' ./reconcile'
2
2
import {
3
3
DependencyList ,
4
4
Reducer ,
5
5
IFiber ,
6
6
Dispatch ,
7
7
SetStateAction ,
8
8
EffectCallback ,
9
- HookTypes ,
10
9
RefObject ,
11
- IEffect ,
12
10
FreNode ,
13
- } from "./type"
11
+ HookList ,
12
+ HookEffect ,
13
+ HookReducer ,
14
+ HookMemo ,
15
+ } from './type'
14
16
15
17
const EMPTY_ARR = [ ]
16
18
@@ -28,15 +30,15 @@ export const useReducer = <S, A>(
28
30
reducer ?: Reducer < S , A > ,
29
31
initState ?: S
30
32
) : [ S , Dispatch < A > ] => {
31
- const [ hook , current ] : [ any , IFiber ] = getHook < S > ( cursor ++ )
33
+ const [ hook , current ] : [ any , IFiber ] = getHook < HookReducer > ( cursor ++ )
32
34
if ( hook . length === 0 ) {
33
35
hook [ 0 ] = initState
34
36
hook [ 1 ] = ( value : A | Dispatch < A > ) => {
35
37
let v = reducer
36
38
? reducer ( hook [ 0 ] , value as any )
37
39
: isFn ( value )
38
- ? value ( hook [ 0 ] )
39
- : value
40
+ ? value ( hook [ 0 ] )
41
+ : value
40
42
if ( hook [ 0 ] !== v ) {
41
43
hook [ 0 ] = v
42
44
update ( current )
@@ -47,31 +49,31 @@ export const useReducer = <S, A>(
47
49
}
48
50
49
51
export const useEffect = ( cb : EffectCallback , deps ?: DependencyList ) : void => {
50
- return effectImpl ( cb , deps ! , " effect" )
52
+ return effectImpl ( cb , deps ! , ' effect' )
51
53
}
52
54
53
55
export const useLayout = ( cb : EffectCallback , deps ?: DependencyList ) : void => {
54
- return effectImpl ( cb , deps ! , " layout" )
56
+ return effectImpl ( cb , deps ! , ' layout' )
55
57
}
56
58
57
59
const effectImpl = (
58
60
cb : EffectCallback ,
59
61
deps : DependencyList ,
60
- key : HookTypes
62
+ key : 'effect' | 'layout'
61
63
) : void => {
62
- const [ hook , current ] = getHook ( cursor ++ )
64
+ const [ hook , current ] = getHook < HookEffect > ( cursor ++ )
63
65
if ( isChanged ( hook [ 1 ] , deps ) ) {
64
66
hook [ 0 ] = cb
65
67
hook [ 1 ] = deps
66
- current . hooks [ key ] . push ( hook )
68
+ current . hooks [ key ] . push ( hook as Required < HookEffect > )
67
69
}
68
70
}
69
71
70
72
export const useMemo = < S = Function > (
71
73
cb : ( ) => S ,
72
74
deps ?: DependencyList
73
75
) : S => {
74
- const hook = getHook < S > ( cursor ++ ) [ 0 ]
76
+ const hook = getHook < HookMemo > ( cursor ++ ) [ 0 ]
75
77
if ( isChanged ( hook [ 1 ] , deps ! ) ) {
76
78
hook [ 1 ] = deps
77
79
return ( hook [ 0 ] = cb ( ) )
@@ -90,39 +92,37 @@ export const useRef = <T>(current: T): RefObject<T> => {
90
92
return useMemo ( ( ) => ( { current } ) , [ ] )
91
93
}
92
94
93
- export const getHook = < S = Function | undefined , Dependency = any > (
94
- cursor : number
95
- ) : [ [ S , Dependency ] , IFiber ] => {
95
+ export const getHook = < T extends HookList = HookList > ( cursor : number ) => {
96
96
const current : IFiber < any > = getCurrentFiber ( )
97
97
const hooks =
98
98
current . hooks || ( current . hooks = { list : [ ] , effect : [ ] , layout : [ ] } )
99
99
if ( cursor >= hooks . list . length ) {
100
- hooks . list . push ( [ ] as IEffect )
100
+ hooks . list . push ( [ ] as any )
101
101
}
102
- return [ ( hooks . list [ cursor ] as unknown ) as [ S , Dependency ] , current ]
102
+ return [ hooks . list [ cursor ] , current ] as unknown as [ Partial < T > , IFiber ]
103
103
}
104
104
105
105
export type ContextType < T > = {
106
- ( { value, children } : { value : T , children : FreNode } ) : FreNode ;
107
- initialValue : T ;
106
+ ( { value, children } : { value : T ; children : FreNode } ) : FreNode
107
+ initialValue : T
108
108
}
109
109
110
- type SubscriberCb = ( ) => void ;
110
+ type SubscriberCb = ( ) => void
111
111
112
112
export const createContext = < T > ( initialValue : T ) : ContextType < T > => {
113
113
const contextComponent : ContextType < T > = ( { value, children } ) => {
114
114
const valueRef = useRef ( value )
115
115
const subscribers = useMemo ( ( ) => new Set < SubscriberCb > ( ) , EMPTY_ARR )
116
116
117
117
if ( valueRef . current !== value ) {
118
- valueRef . current = value ;
118
+ valueRef . current = value
119
119
subscribers . forEach ( ( subscriber ) => subscriber ( ) )
120
120
}
121
121
122
122
return children
123
123
}
124
- contextComponent . initialValue = initialValue ;
125
- return contextComponent ;
124
+ contextComponent . initialValue = initialValue
125
+ return contextComponent
126
126
}
127
127
128
128
export const useContext = < T > ( contextType : ContextType < T > ) : T => {
@@ -132,16 +132,19 @@ export const useContext = <T>(contextType: ContextType<T>): T => {
132
132
133
133
useEffect ( ( ) => {
134
134
return ( ) => subscribersSet && subscribersSet . delete ( triggerUpdate )
135
- } , EMPTY_ARR ) ;
135
+ } , EMPTY_ARR )
136
136
137
137
let contextFiber = getCurrentFiber ( ) . parent
138
138
while ( contextFiber && contextFiber . type !== contextType ) {
139
139
contextFiber = contextFiber . parent
140
140
}
141
141
142
142
if ( contextFiber ) {
143
- const hooks = contextFiber . hooks . list as unknown as [ [ RefObject < T > ] , [ Set < SubscriberCb > ] ]
144
- const [ [ value ] , [ subscribers ] ] = hooks ;
143
+ const hooks = contextFiber . hooks . list as unknown as [
144
+ [ RefObject < T > ] ,
145
+ [ Set < SubscriberCb > ]
146
+ ]
147
+ const [ [ value ] , [ subscribers ] ] = hooks
145
148
146
149
subscribersSet = subscribers . add ( triggerUpdate )
147
150
@@ -151,6 +154,10 @@ export const useContext = <T>(contextType: ContextType<T>): T => {
151
154
}
152
155
}
153
156
154
- export const isChanged = ( a : DependencyList , b : DependencyList ) => {
155
- return ! a || a . length !== b . length || b . some ( ( arg , index ) => ! Object . is ( arg , a [ index ] ) )
157
+ export const isChanged = ( a : DependencyList | undefined , b : DependencyList ) => {
158
+ return (
159
+ ! a ||
160
+ a . length !== b . length ||
161
+ b . some ( ( arg , index ) => ! Object . is ( arg , a [ index ] ) )
162
+ )
156
163
}
0 commit comments