11import { CSSProperties , useEffect , useRef , useState } from 'react' ;
2- import { EventEmitter , Form as FormClass , Webform } from '@formio/js' ;
2+ import { EventEmitter , Form as FormClass , Webform , Utils } from '@formio/js' ;
33import { Component , Form as CoreFormType } from '@formio/core' ;
44import structuredClone from '@ungap/structured-clone' ;
55
@@ -228,9 +228,7 @@ const createWebformInstance = async (
228228 if ( ! options ?. events ) {
229229 options . events = getDefaultEmitter ( ) ;
230230 }
231- if ( typeof formSource !== 'string' ) {
232- formSource = structuredClone ( formSource ) ;
233- }
231+
234232 const promise = FormConstructor
235233 ? new FormConstructor ( element , formSource , options )
236234 : new FormClass ( element , formSource , options ) ;
@@ -253,6 +251,7 @@ const getEffectiveProps = (props: FormProps) => {
253251
254252export const Form = ( props : FormProps ) => {
255253 const renderElement = useRef < HTMLDivElement | null > ( null ) ;
254+ const currentFormJson = useRef < FormType | null > ( null ) ;
256255 const { formConstructor, formSource, formReadyCallback } = getEffectiveProps ( props ) ;
257256 const {
258257 src,
@@ -278,6 +277,14 @@ export const Form = (props: FormProps) => {
278277 } , [ formInstance ] ) ;
279278
280279 useEffect ( ( ) => {
280+ if (
281+ typeof formSource === 'object' &&
282+ currentFormJson . current &&
283+ Utils . _ . isEqual ( currentFormJson . current , formSource )
284+ ) {
285+ return ;
286+ }
287+
281288 const createInstance = async ( ) => {
282289 if ( renderElement . current === null ) {
283290 console . warn ( 'Form element not found' ) ;
@@ -288,10 +295,12 @@ export const Form = (props: FormProps) => {
288295 console . warn ( 'Form source not found' ) ;
289296 return ;
290297 }
291-
298+ currentFormJson . current = formSource && typeof formSource !== 'string'
299+ ? structuredClone ( formSource )
300+ : null ;
292301 const instance = await createWebformInstance (
293302 formConstructor ,
294- formSource ,
303+ currentFormJson . current || formSource ,
295304 renderElement . current ,
296305 options ,
297306 ) ;
@@ -327,17 +336,15 @@ export const Form = (props: FormProps) => {
327336 ] ) ;
328337
329338 useEffect ( ( ) => {
339+ let onAnyHandler = null ;
330340 if ( formInstance && Object . keys ( handlers ) . length > 0 ) {
331- formInstance . onAny ( ( ...args : [ string , ...any [ ] ] ) =>
332- onAnyEvent ( handlers , ...args ) ,
333- ) ;
341+ onAnyHandler = ( ...args : [ string , ...any [ ] ] ) => onAnyEvent ( handlers , ...args ) ;
342+ formInstance . onAny ( onAnyHandler ) ;
334343 }
335344
336345 return ( ) => {
337- if ( formInstance && Object . keys ( handlers ) . length > 0 ) {
338- formInstance . offAny ( ( ...args : [ string , ...any [ ] ] ) =>
339- onAnyEvent ( handlers , ...args ) ,
340- ) ;
346+ if ( formInstance && onAnyHandler ) {
347+ formInstance . offAny ( onAnyHandler ) ;
341348 }
342349 } ;
343350 } , [ formInstance , handlers ] ) ;
0 commit comments