@@ -76,9 +76,14 @@ export interface InternalFieldProps<Values = any> {
76
76
77
77
/** @private Passed by Form.List props. Do not use since it will break by path check. */
78
78
isListField ?: boolean ;
79
+
80
+ /** @private Pass context as prop instead of context api
81
+ * since class component can not get context in constructor */
82
+ fieldContext : InternalFormInstance ;
79
83
}
80
84
81
- export interface FieldProps < Values = any > extends Omit < InternalFieldProps < Values > , 'name' > {
85
+ export interface FieldProps < Values = any >
86
+ extends Omit < InternalFieldProps < Values > , 'name' | 'fieldContext' > {
82
87
name ?: NamePath ;
83
88
}
84
89
@@ -87,24 +92,21 @@ export interface FieldState {
87
92
}
88
93
89
94
// We use Class instead of Hooks here since it will cost much code by using Hooks.
90
- class Field extends React . Component < InternalFieldProps , FieldState , InternalFormInstance >
91
- implements FieldEntity {
95
+ class Field extends React . Component < InternalFieldProps , FieldState > implements FieldEntity {
92
96
public static contextType = FieldContext ;
93
97
94
98
public static defaultProps = {
95
99
trigger : 'onChange' ,
96
100
valuePropName : 'value' ,
97
101
} ;
98
102
99
- context : InternalFormInstance ;
100
-
101
103
public state = {
102
104
resetCount : 0 ,
103
105
} ;
104
106
105
107
private cancelRegisterFunc : ( isListField ?: boolean , preserve ?: boolean ) => void | null = null ;
106
108
107
- private destroy = false ;
109
+ private mounted = false ;
108
110
109
111
/**
110
112
* Follow state should not management in State since it will async update by React.
@@ -122,11 +124,21 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
122
124
private errors : string [ ] = [ ] ;
123
125
124
126
// ============================== Subscriptions ==============================
127
+ constructor ( props : InternalFieldProps ) {
128
+ super ( props ) ;
129
+
130
+ // Register on init
131
+ if ( props . fieldContext ) {
132
+ const { getInternalHooks } : InternalFormInstance = props . fieldContext ;
133
+ const { registerField } = getInternalHooks ( HOOK_MARK ) ;
134
+ this . cancelRegisterFunc = registerField ( this ) ;
135
+ }
136
+ }
137
+
125
138
public componentDidMount ( ) {
126
139
const { shouldUpdate } = this . props ;
127
- const { getInternalHooks } : InternalFormInstance = this . context ;
128
- const { registerField } = getInternalHooks ( HOOK_MARK ) ;
129
- this . cancelRegisterFunc = registerField ( this ) ;
140
+
141
+ this . mounted = true ;
130
142
131
143
// One more render for component in case fields not ready
132
144
if ( shouldUpdate === true ) {
@@ -136,7 +148,7 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
136
148
137
149
public componentWillUnmount ( ) {
138
150
this . cancelRegister ( ) ;
139
- this . destroy = true ;
151
+ this . mounted = false ;
140
152
}
141
153
142
154
public cancelRegister = ( ) => {
@@ -150,32 +162,32 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
150
162
151
163
// ================================== Utils ==================================
152
164
public getNamePath = ( ) : InternalNamePath => {
153
- const { name } = this . props ;
154
- const { prefixName = [ ] } : InternalFormInstance = this . context ;
165
+ const { name, fieldContext } = this . props ;
166
+ const { prefixName = [ ] } : InternalFormInstance = fieldContext ;
155
167
156
168
return name !== undefined ? [ ...prefixName , ...name ] : [ ] ;
157
169
} ;
158
170
159
171
public getRules = ( ) : RuleObject [ ] => {
160
- const { rules = [ ] } = this . props ;
172
+ const { rules = [ ] , fieldContext } = this . props ;
161
173
162
174
return rules . map (
163
175
( rule : Rule ) : RuleObject => {
164
176
if ( typeof rule === 'function' ) {
165
- return rule ( this . context ) ;
177
+ return rule ( fieldContext ) ;
166
178
}
167
179
return rule ;
168
180
} ,
169
181
) ;
170
182
} ;
171
183
172
184
public reRender ( ) {
173
- if ( this . destroy ) return ;
185
+ if ( ! this . mounted ) return ;
174
186
this . forceUpdate ( ) ;
175
187
}
176
188
177
189
public refresh = ( ) => {
178
- if ( this . destroy ) return ;
190
+ if ( ! this . mounted ) return ;
179
191
180
192
/**
181
193
* Clean up current node.
@@ -373,7 +385,7 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
373
385
const meta = this . getMeta ( ) ;
374
386
375
387
return {
376
- ...this . getOnlyChild ( children ( this . getControlled ( ) , meta , this . context ) ) ,
388
+ ...this . getOnlyChild ( children ( this . getControlled ( ) , meta , this . props . fieldContext ) ) ,
377
389
isFunction : true ,
378
390
} ;
379
391
}
@@ -389,7 +401,7 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
389
401
390
402
// ============================== Field Control ==============================
391
403
public getValue = ( store ?: Store ) => {
392
- const { getFieldsValue } : FormInstance = this . context ;
404
+ const { getFieldsValue } : FormInstance = this . props . fieldContext ;
393
405
const namePath = this . getNamePath ( ) ;
394
406
return getValue ( store || getFieldsValue ( true ) , namePath ) ;
395
407
} ;
@@ -402,13 +414,14 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
402
414
normalize,
403
415
valuePropName,
404
416
getValueProps,
417
+ fieldContext,
405
418
} = this . props ;
406
419
407
420
const mergedValidateTrigger =
408
- validateTrigger !== undefined ? validateTrigger : this . context . validateTrigger ;
421
+ validateTrigger !== undefined ? validateTrigger : fieldContext . validateTrigger ;
409
422
410
423
const namePath = this . getNamePath ( ) ;
411
- const { getInternalHooks, getFieldsValue } : InternalFormInstance = this . context ;
424
+ const { getInternalHooks, getFieldsValue } : InternalFormInstance = fieldContext ;
412
425
const { dispatch } = getInternalHooks ( HOOK_MARK ) ;
413
426
const value = this . getValue ( ) ;
414
427
const mergedGetValueProps = getValueProps || ( ( val : StoreValue ) => ( { [ valuePropName ] : val } ) ) ;
@@ -502,6 +515,8 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
502
515
}
503
516
504
517
function WrapperField < Values = any > ( { name, ...restProps } : FieldProps < Values > ) {
518
+ const fieldContext = React . useContext ( FieldContext ) ;
519
+
505
520
const namePath = name !== undefined ? getNamePath ( name ) : undefined ;
506
521
507
522
let key : string = 'keep' ;
@@ -516,7 +531,7 @@ function WrapperField<Values = any>({ name, ...restProps }: FieldProps<Values>)
516
531
) ;
517
532
}
518
533
519
- return < Field key = { key } name = { namePath } { ...restProps } /> ;
534
+ return < Field key = { key } name = { namePath } { ...restProps } fieldContext = { fieldContext } /> ;
520
535
}
521
536
522
537
export default WrapperField ;
0 commit comments