@@ -126,7 +126,6 @@ type FormIndexKeyMap = Record<number, IndexKeyMap>;
126126export type FormRefKeyMap = Record < number , RefKeyMap > ;
127127
128128export function useInnerContext ( skip ?: boolean ) {
129- // const formIndex = React.useRef<number>(0);
130129 const [ lastKey , setLastKey ] = useRefState < string | undefined > ( undefined ) ;
131130 const refIndex = React . useRef < number > ( 0 ) ;
132131
@@ -305,20 +304,43 @@ export default function useFormState<T>(
305304 const [ wasSubmitted , setWasSubmitted ] = useRefState < boolean > ( false ) ;
306305 const [ touched , sTouched ] = useRefState < BooleanUtility < T > > ( { } ) ;
307306 const [ focusedOnce , sFocusedOnce ] = useRefState < BooleanUtility < T > > ( { } ) ;
307+ const initialErrorCache = React . useRef < ErrorUtility < T > > ( { } ) ;
308308 const [ errors , sErrors ] = useRefState < ErrorUtility < T > > ( { } ) ;
309309 const [ values , setValues ] = useRefState < T > ( initialState ) ;
310310 const [ lastCharacters , setLastCharacters ] = useRefState <
311311 FieldsLastCharacters < T >
312312 > ( { } ) ;
313313
314+ React . useEffect ( ( ) => {
315+ // render optimization because we don't want to re-render on every field at the beginning of the onLayout calls :)
316+ const timer = setTimeout ( ( ) => {
317+ sErrors ( initialErrorCache . current ) ;
318+ } , 100 ) ;
319+ return ( ) => {
320+ clearTimeout ( timer ) ;
321+ } ;
322+ } , [ initialErrorCache , sErrors ] ) ;
323+
314324 const setError = React . useCallback (
315- < K extends DotNestedKeys < T > > ( k : K , v : boolean | string | undefined ) => {
325+ < K extends DotNestedKeys < T > > (
326+ k : K ,
327+ v : boolean | string | undefined ,
328+ initial ?: boolean
329+ ) => {
316330 const error = deepGet ( errors . current , k ) ;
317331 if ( v !== error ) {
318- sErrors ( ( prev ) => deepSet ( prev , k , v ) as any ) ;
332+ if ( initial ) {
333+ initialErrorCache . current = deepSet (
334+ initialErrorCache . current || { } ,
335+ k ,
336+ v
337+ ) as any ;
338+ } else {
339+ sErrors ( ( prev ) => deepSet ( prev , k , v ) as any ) ;
340+ }
319341 }
320342 } ,
321- [ errors , sErrors ]
343+ [ errors , sErrors , initialErrorCache ]
322344 ) ;
323345
324346 const clearErrors = React . useCallback ( ( ) => {
@@ -330,7 +352,8 @@ export default function useFormState<T>(
330352 k : K ,
331353 h : Customizing < T , K > | CustomizingRaw < T , K > | undefined ,
332354 v : GetFieldType < T , K > ,
333- allV : T
355+ allV : T ,
356+ initial ?: boolean
334357 ) => {
335358 let err : boolean | string | undefined ;
336359
@@ -348,7 +371,8 @@ export default function useFormState<T>(
348371 }
349372 setError (
350373 k ,
351- err === true || err === undefined || err === null ? false : err
374+ err === true || err === undefined || err === null ? false : err ,
375+ initial
352376 ) ;
353377 } ,
354378 [ setError ]
@@ -440,7 +464,7 @@ export default function useFormState<T>(
440464 referencedCallback ( `layout.${ k } ` , ( e : LayoutChangeEvent ) => {
441465 h ?. onLayout ?.( e ) ;
442466 const value = deepGet ( values . current , k ) ;
443- checkError ( k as DotNestedKeys < T > , h , value as any , values . current ) ;
467+ checkError ( k as DotNestedKeys < T > , h , value as any , values . current , true ) ;
444468 } ) ;
445469
446470 const text = < K extends DotNestedKeys < T > > (
0 commit comments