diff --git a/packages/core/admin/admin/src/content-manager/components/NonRepeatableComponent/index.js b/packages/core/admin/admin/src/content-manager/components/NonRepeatableComponent/index.js index 721472d1ab..06c0031153 100644 --- a/packages/core/admin/admin/src/content-manager/components/NonRepeatableComponent/index.js +++ b/packages/core/admin/admin/src/content-manager/components/NonRepeatableComponent/index.js @@ -9,6 +9,7 @@ import { Stack } from '@strapi/design-system/Stack'; import { useContentTypeLayout } from '../../hooks'; import FieldComponent from '../FieldComponent'; import Inputs from '../Inputs'; +import useLazyComponents from '../../hooks/useLazyComponents'; const NonRepeatableComponent = ({ componentUid, isFromDynamicZone, isNested, name }) => { const { getComponentLayout } = useContentTypeLayout(); @@ -18,6 +19,8 @@ const NonRepeatableComponent = ({ componentUid, isFromDynamicZone, isNested, nam ); const fields = componentLayoutData.layouts.edit; + const { lazyComponentStore } = useLazyComponents(); + return ( ); diff --git a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js index 41fcb02fc1..50d89e4f01 100644 --- a/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js +++ b/packages/core/admin/admin/src/content-manager/components/RepeatableComponent/DraggedItem/index.js @@ -21,6 +21,7 @@ import Preview from './Preview'; import DraggingSibling from './DraggingSibling'; import { CustomIconButton } from './IconButtonCustoms'; import { connect, select } from './utils'; +import useLazyComponents from '../../../hooks/useLazyComponents'; const DragButton = styled.span` display: flex; @@ -177,6 +178,8 @@ const DraggedItem = ({ const accordionTitle = toString(displayedValue); const accordionHasError = hasErrors ? 'error' : undefined; + const { lazyComponentStore } = useLazyComponents(); + return ( {isDragging && } @@ -273,6 +276,7 @@ const DraggedItem = ({ // onBlur={hasErrors ? checkFormErrors : null} queryInfos={queryInfos} size={size} + customFieldInputs={lazyComponentStore} /> ); diff --git a/packages/core/admin/admin/src/content-manager/hooks/useLazyComponents/index.js b/packages/core/admin/admin/src/content-manager/hooks/useLazyComponents/index.js index 1b3ddf0462..496eefc9c4 100644 --- a/packages/core/admin/admin/src/content-manager/hooks/useLazyComponents/index.js +++ b/packages/core/admin/admin/src/content-manager/hooks/useLazyComponents/index.js @@ -1,42 +1,69 @@ import { useEffect, useState } from 'react'; import { useCustomFields } from '@strapi/helper-plugin'; +const componentStore = new Map(); + /** * @description * A hook to lazy load custom field components * @param {Array.} componentUids - The uids to look up components * @returns object */ -const useLazyComponents = (componentUids) => { +const useLazyComponents = (componentUids = []) => { const [lazyComponentStore, setLazyComponentStore] = useState({}); const [loading, setLoading] = useState(true); const customFieldsRegistry = useCustomFields(); useEffect(() => { + const setStore = (store) => { + setLazyComponentStore(store); + setLoading(false); + }; + + const populateStoreWithCache = () => { + const internalStore = {}; + + componentStore.forEach((comp, uid) => { + internalStore[uid] = comp; + }); + + setStore(internalStore); + }; + const lazyLoadComponents = async (uids, components) => { const modules = await Promise.all(components); + const internalStore = {}; + uids.forEach((uid, index) => { - if (!Object.keys(lazyComponentStore).includes(uid)) { - setLazyComponentStore({ ...lazyComponentStore, [uid]: modules[index].default }); - } + componentStore.set(uid, modules[index].default); + internalStore[uid] = modules[index].default; }); + + setStore(internalStore); }; if (componentUids.length) { - const componentPromises = componentUids.map((uid) => { + /** + * These uids are not in the component store therefore we need to get the components + */ + const newUids = componentUids.filter((uid) => !componentStore.get(uid)); + + const componentPromises = newUids.map((uid) => { const customField = customFieldsRegistry.get(uid); return customField.components.Input(); }); - lazyLoadComponents(componentUids, componentPromises); + if (componentPromises.length > 0) { + lazyLoadComponents(newUids, componentPromises); + } else { + populateStoreWithCache(); + } + } else if (loading) { + populateStoreWithCache(); } - - if (componentUids.length === Object.keys(lazyComponentStore).length) { - setLoading(false); - } - }, [componentUids, customFieldsRegistry, loading, lazyComponentStore]); + }, [componentUids, customFieldsRegistry, loading]); return { isLazyLoading: loading, lazyComponentStore }; };