@@ -129,6 +129,7 @@ export const useForm = <
129129 watch,
130130 setValue,
131131 getValues,
132+ reset,
132133 handleSubmit : handleSubmitReactHookForm ,
133134 setError,
134135 formState : { dirtyFields } ,
@@ -253,39 +254,28 @@ export const useForm = <
253254 } ) ;
254255 } ;
255256
256- // On query load, attempt a first sync after registration effects run.
257+ // On query load, reset the form with server data natively.
258+ // This ensures useFieldArray and other RHF internals are properly initialized.
259+ const initialLoadRef = React . useRef ( true ) ;
257260 useEffect ( ( ) => {
258261 const data = query ?. data ?. data ;
259262 if ( ! data ) {
260263 queryDataRef . current = undefined ;
261264 syncedFieldsRef . current = new Set ( ) ;
262265 mountedFieldsRef . current = new Set ( ) ;
266+ initialLoadRef . current = true ;
263267 return ;
264268 }
265269
266- let isActive = true ;
267-
268- const applyQueryValues = ( ) => {
269- if ( ! isActive ) return ;
270-
271- applyValuesToFields ( getRegisteredFields ( ) , data , false ) ;
272- } ;
273-
274270 queryDataRef . current = data ;
275- syncedFieldsRef . current = new Set ( ) ;
276271 mountedFieldsRef . current = getMountedFields ( ) ;
277272
278- // defer until after field registration effects
279- if ( typeof queueMicrotask === "function" ) {
280- queueMicrotask ( applyQueryValues ) ;
281- } else {
282- Promise . resolve ( ) . then ( applyQueryValues ) ;
273+ if ( initialLoadRef . current ) {
274+ initialLoadRef . current = false ;
275+ syncedFieldsRef . current = new Set ( ) ;
276+ reset ( data as unknown as TVariables , { keepDirtyValues : true } ) ;
283277 }
284-
285- return ( ) => {
286- isActive = false ;
287- } ;
288- } , [ query ?. data , setValue , getValues ] ) ;
278+ } , [ query ?. data , reset , getValues ] ) ;
289279
290280 // Re-sync when new fields register; do not override user edits.
291281 useEffect ( ( ) => {
0 commit comments