Skip to content

Commit 1ceda0d

Browse files
authored
Merge pull request #598 from formio/fixed-instance-recreation-when-json-not-changed
do not recreate form instance if the form json is not changed deeply
2 parents 93938ce + 928e477 commit 1ceda0d

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

src/components/Form.tsx

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { 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';
33
import { Component, Form as CoreFormType } from '@formio/core';
44
import 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

254252
export 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

Comments
 (0)