From d1b69cb8f98672423616b40f245d61120dbf21c4 Mon Sep 17 00:00:00 2001 From: Nikita Zolotykh <58661343+bocembocem@users.noreply.github.com> Date: Thu, 17 Oct 2024 12:20:03 +0200 Subject: [PATCH] feat: add ability to use external values for shared context (#240) --- src/lib/core/components/Form/DynamicField.tsx | 4 +++- .../components/Form/hooks/useFormSharedStore.tsx | 16 ++++++++++++++-- src/lib/core/components/View/DynamicView.tsx | 4 +++- .../components/View/hooks/useViewSharedStore.tsx | 16 ++++++++++++++-- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/lib/core/components/Form/DynamicField.tsx b/src/lib/core/components/Form/DynamicField.tsx index 4ebc37ad..a86ed7b6 100644 --- a/src/lib/core/components/Form/DynamicField.tsx +++ b/src/lib/core/components/Form/DynamicField.tsx @@ -33,6 +33,7 @@ export interface DynamicFieldProps { withoutInsertFFDebounce?: boolean; destroyOnUnregister?: boolean; mutators?: DynamicFormMutators; + shared?: Record; __mirror?: WonderMirror; } @@ -46,6 +47,7 @@ export const DynamicField: React.FC = ({ withoutInsertFFDebounce, destroyOnUnregister = true, mutators: externalMutators, + shared: externalShared, __mirror, }) => { const DynamicFormsCtx = useCreateContext(); @@ -54,7 +56,7 @@ export const DynamicField: React.FC = ({ const watcher = useIntegrationFF(store, withoutInsertFFDebounce, destroyOnUnregister); const {mutatorsStore, mutateDFState} = useMutators(externalMutators); const {store: searchStore, setField, removeField, isHiddenField} = useSearchStore(); - const shared = useFormSharedStore(); + const shared = useFormSharedStore(externalShared); const context = React.useMemo( () => ({ diff --git a/src/lib/core/components/Form/hooks/useFormSharedStore.tsx b/src/lib/core/components/Form/hooks/useFormSharedStore.tsx index 4f537468..dd95ab94 100644 --- a/src/lib/core/components/Form/hooks/useFormSharedStore.tsx +++ b/src/lib/core/components/Form/hooks/useFormSharedStore.tsx @@ -1,12 +1,24 @@ import React from 'react'; -export const useFormSharedStore = () => { - const [store, setStore] = React.useState({}); +export const useFormSharedStore = (shared?: Record) => { + const firstRender = React.useRef(true); + const [store, setStore] = React.useState(shared || {}); const onChangeShared = React.useCallback( (name: string, value: any) => setStore((s) => ({...s, [name]: value})), [setStore], ); + React.useEffect(() => { + if (firstRender.current) { + firstRender.current = false; + } else if (shared) { + setStore({ + ...store, + ...shared, + }); + } + }, [shared]); + return {store, onChangeShared}; }; diff --git a/src/lib/core/components/View/DynamicView.tsx b/src/lib/core/components/View/DynamicView.tsx index f23e87cc..3126f732 100644 --- a/src/lib/core/components/View/DynamicView.tsx +++ b/src/lib/core/components/View/DynamicView.tsx @@ -21,6 +21,7 @@ export interface DynamicViewProps { }>; Monaco?: React.ComponentType; showLayoutDescription?: boolean; + shared?: Record; } export const DynamicView = ({ @@ -30,9 +31,10 @@ export const DynamicView = ({ Link, Monaco, showLayoutDescription, + shared: externalShared, }: DynamicViewProps) => { const DynamicFormsCtx = useCreateContext(); - const shared = useViewSharedStore(); + const shared = useViewSharedStore(externalShared); const context = React.useMemo( () => ({ diff --git a/src/lib/core/components/View/hooks/useViewSharedStore.tsx b/src/lib/core/components/View/hooks/useViewSharedStore.tsx index 1ebfa121..1a8e38fe 100644 --- a/src/lib/core/components/View/hooks/useViewSharedStore.tsx +++ b/src/lib/core/components/View/hooks/useViewSharedStore.tsx @@ -1,12 +1,24 @@ import React from 'react'; -export const useViewSharedStore = () => { - const [store, setStore] = React.useState({}); +export const useViewSharedStore = (shared?: Record) => { + const firstRender = React.useRef(true); + const [store, setStore] = React.useState(shared || {}); const onChangeShared = React.useCallback( (name: string, value: any) => setStore((s) => ({...s, [name]: value})), [setStore], ); + React.useEffect(() => { + if (firstRender.current) { + firstRender.current = false; + } else if (shared) { + setStore({ + ...store, + ...shared, + }); + } + }, [shared]); + return {store, onChangeShared}; };