Skip to content

Commit

Permalink
do not recreate form instance if the form json is not changed deeply
Browse files Browse the repository at this point in the history
  • Loading branch information
TanyaGashtold committed Jan 29, 2025
1 parent 93938ce commit 928e477
Showing 1 changed file with 20 additions and 13 deletions.
33 changes: 20 additions & 13 deletions src/components/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CSSProperties, useEffect, useRef, useState } from 'react';
import { EventEmitter, Form as FormClass, Webform } from '@formio/js';
import { EventEmitter, Form as FormClass, Webform, Utils } from '@formio/js';
import { Component, Form as CoreFormType } from '@formio/core';
import structuredClone from '@ungap/structured-clone';

Expand Down Expand Up @@ -228,9 +228,7 @@ const createWebformInstance = async (
if (!options?.events) {
options.events = getDefaultEmitter();
}
if (typeof formSource !== 'string') {
formSource = structuredClone(formSource);
}

const promise = FormConstructor
? new FormConstructor(element, formSource, options)
: new FormClass(element, formSource, options);
Expand All @@ -253,6 +251,7 @@ const getEffectiveProps = (props: FormProps) => {

export const Form = (props: FormProps) => {
const renderElement = useRef<HTMLDivElement | null>(null);
const currentFormJson = useRef<FormType | null>(null);
const { formConstructor, formSource, formReadyCallback } = getEffectiveProps(props);
const {
src,
Expand All @@ -278,6 +277,14 @@ export const Form = (props: FormProps) => {
}, [formInstance]);

useEffect(() => {
if (
typeof formSource === 'object' &&
currentFormJson.current &&
Utils._.isEqual(currentFormJson.current, formSource)
) {
return;
}

const createInstance = async () => {
if (renderElement.current === null) {
console.warn('Form element not found');
Expand All @@ -288,10 +295,12 @@ export const Form = (props: FormProps) => {
console.warn('Form source not found');
return;
}

currentFormJson.current = formSource && typeof formSource !== 'string'
? structuredClone(formSource)
: null;
const instance = await createWebformInstance(
formConstructor,
formSource,
currentFormJson.current || formSource,
renderElement.current,
options,
);
Expand Down Expand Up @@ -327,17 +336,15 @@ export const Form = (props: FormProps) => {
]);

useEffect(() => {
let onAnyHandler = null;
if (formInstance && Object.keys(handlers).length > 0) {
formInstance.onAny((...args: [string, ...any[]]) =>
onAnyEvent(handlers, ...args),
);
onAnyHandler = (...args: [string, ...any[]]) => onAnyEvent(handlers, ...args);
formInstance.onAny(onAnyHandler);
}

Check warning on line 343 in src/components/Form.tsx

View workflow job for this annotation

GitHub Actions / setup

Unexpected any. Specify a different type

Check warning on line 343 in src/components/Form.tsx

View workflow job for this annotation

GitHub Actions / setup

Unexpected any. Specify a different type

Check warning on line 343 in src/components/Form.tsx

View workflow job for this annotation

GitHub Actions / publish

Unexpected any. Specify a different type

return () => {
if (formInstance && Object.keys(handlers).length > 0) {
formInstance.offAny((...args: [string, ...any[]]) =>
onAnyEvent(handlers, ...args),
);
if (formInstance && onAnyHandler) {
formInstance.offAny(onAnyHandler);
}
};
}, [formInstance, handlers]);
Expand Down

0 comments on commit 928e477

Please sign in to comment.