@@ -76,9 +76,14 @@ export interface InternalFieldProps<Values = any> {
7676
7777 /** @private Passed by Form.List props. Do not use since it will break by path check. */
7878 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 ;
7983}
8084
81- export interface FieldProps < Values = any > extends Omit < InternalFieldProps < Values > , 'name' > {
85+ export interface FieldProps < Values = any >
86+ extends Omit < InternalFieldProps < Values > , 'name' | 'fieldContext' > {
8287 name ?: NamePath ;
8388}
8489
@@ -87,24 +92,21 @@ export interface FieldState {
8792}
8893
8994// 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 {
9296 public static contextType = FieldContext ;
9397
9498 public static defaultProps = {
9599 trigger : 'onChange' ,
96100 valuePropName : 'value' ,
97101 } ;
98102
99- context : InternalFormInstance ;
100-
101103 public state = {
102104 resetCount : 0 ,
103105 } ;
104106
105107 private cancelRegisterFunc : ( isListField ?: boolean , preserve ?: boolean ) => void | null = null ;
106108
107- private destroy = false ;
109+ private mounted = false ;
108110
109111 /**
110112 * 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
122124 private errors : string [ ] = [ ] ;
123125
124126 // ============================== 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+
125138 public componentDidMount ( ) {
126139 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 ;
130142
131143 // One more render for component in case fields not ready
132144 if ( shouldUpdate === true ) {
@@ -136,7 +148,7 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
136148
137149 public componentWillUnmount ( ) {
138150 this . cancelRegister ( ) ;
139- this . destroy = true ;
151+ this . mounted = false ;
140152 }
141153
142154 public cancelRegister = ( ) => {
@@ -150,32 +162,32 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
150162
151163 // ================================== Utils ==================================
152164 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 ;
155167
156168 return name !== undefined ? [ ...prefixName , ...name ] : [ ] ;
157169 } ;
158170
159171 public getRules = ( ) : RuleObject [ ] => {
160- const { rules = [ ] } = this . props ;
172+ const { rules = [ ] , fieldContext } = this . props ;
161173
162174 return rules . map (
163175 ( rule : Rule ) : RuleObject => {
164176 if ( typeof rule === 'function' ) {
165- return rule ( this . context ) ;
177+ return rule ( fieldContext ) ;
166178 }
167179 return rule ;
168180 } ,
169181 ) ;
170182 } ;
171183
172184 public reRender ( ) {
173- if ( this . destroy ) return ;
185+ if ( ! this . mounted ) return ;
174186 this . forceUpdate ( ) ;
175187 }
176188
177189 public refresh = ( ) => {
178- if ( this . destroy ) return ;
190+ if ( ! this . mounted ) return ;
179191
180192 /**
181193 * Clean up current node.
@@ -373,7 +385,7 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
373385 const meta = this . getMeta ( ) ;
374386
375387 return {
376- ...this . getOnlyChild ( children ( this . getControlled ( ) , meta , this . context ) ) ,
388+ ...this . getOnlyChild ( children ( this . getControlled ( ) , meta , this . props . fieldContext ) ) ,
377389 isFunction : true ,
378390 } ;
379391 }
@@ -389,7 +401,7 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
389401
390402 // ============================== Field Control ==============================
391403 public getValue = ( store ?: Store ) => {
392- const { getFieldsValue } : FormInstance = this . context ;
404+ const { getFieldsValue } : FormInstance = this . props . fieldContext ;
393405 const namePath = this . getNamePath ( ) ;
394406 return getValue ( store || getFieldsValue ( true ) , namePath ) ;
395407 } ;
@@ -402,13 +414,14 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
402414 normalize,
403415 valuePropName,
404416 getValueProps,
417+ fieldContext,
405418 } = this . props ;
406419
407420 const mergedValidateTrigger =
408- validateTrigger !== undefined ? validateTrigger : this . context . validateTrigger ;
421+ validateTrigger !== undefined ? validateTrigger : fieldContext . validateTrigger ;
409422
410423 const namePath = this . getNamePath ( ) ;
411- const { getInternalHooks, getFieldsValue } : InternalFormInstance = this . context ;
424+ const { getInternalHooks, getFieldsValue } : InternalFormInstance = fieldContext ;
412425 const { dispatch } = getInternalHooks ( HOOK_MARK ) ;
413426 const value = this . getValue ( ) ;
414427 const mergedGetValueProps = getValueProps || ( ( val : StoreValue ) => ( { [ valuePropName ] : val } ) ) ;
@@ -502,6 +515,8 @@ class Field extends React.Component<InternalFieldProps, FieldState, InternalForm
502515}
503516
504517function WrapperField < Values = any > ( { name, ...restProps } : FieldProps < Values > ) {
518+ const fieldContext = React . useContext ( FieldContext ) ;
519+
505520 const namePath = name !== undefined ? getNamePath ( name ) : undefined ;
506521
507522 let key : string = 'keep' ;
@@ -516,7 +531,7 @@ function WrapperField<Values = any>({ name, ...restProps }: FieldProps<Values>)
516531 ) ;
517532 }
518533
519- return < Field key = { key } name = { namePath } { ...restProps } /> ;
534+ return < Field key = { key } name = { namePath } { ...restProps } fieldContext = { fieldContext } /> ;
520535}
521536
522537export default WrapperField ;
0 commit comments