diff --git a/packages/dnb-eufemia/src/extensions/forms/DataContext/Provider/__tests__/Provider.test.tsx b/packages/dnb-eufemia/src/extensions/forms/DataContext/Provider/__tests__/Provider.test.tsx index a2e275a18e2..eb565927b62 100644 --- a/packages/dnb-eufemia/src/extensions/forms/DataContext/Provider/__tests__/Provider.test.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/DataContext/Provider/__tests__/Provider.test.tsx @@ -1,4 +1,4 @@ -import React, { StrictMode, createRef, useContext } from 'react' +import React, { StrictMode, createRef, useContext, useEffect } from 'react' import { act, fireEvent, @@ -2214,8 +2214,12 @@ describe('DataContext.Provider', () => { ) - expect(nestedMockData).toHaveLength(1) - expect(nestedMockData[0]).toEqual(initialData) + expect(nestedMockData).toHaveLength(3) + expect(nestedMockData).toEqual([ + initialData, + initialData, + initialData, + ]) const inputElement = document.querySelector('input') expect(inputElement).toHaveValue('bar') @@ -2247,11 +2251,15 @@ describe('DataContext.Provider', () => { ) - expect(sidecarMockData).toHaveLength(2) - expect(sidecarMockData).toEqual([undefined, initialData]) + expect(sidecarMockData).toHaveLength(3) + expect(sidecarMockData).toEqual([ + undefined, + initialData, + initialData, + ]) - expect(nestedMockData).toHaveLength(1) - expect(nestedMockData).toEqual([initialData]) + expect(nestedMockData).toHaveLength(2) + expect(nestedMockData).toEqual([initialData, initialData]) const [sidecar, nested] = Array.from( document.querySelectorAll('input') @@ -2260,6 +2268,58 @@ describe('DataContext.Provider', () => { expect(nested).toHaveValue('bar') }) + it('should be able to update data from side car', async () => { + const sidecarMockData = [] + const nestedMockData = [] + + const SidecarMock = () => { + const { data, update } = Form.useData(identifier) + + useEffect(() => { + update('/fieldA', () => 'updated A') + update('/fieldB', () => 'updated B') + }, [update]) + + sidecarMockData.push(data) + return null + } + + const NestedMock = () => { + const { data } = Form.useData(identifier) + nestedMockData.push(data) + return + } + + render( + <> + + + + + + + ) + + expect(sidecarMockData).toHaveLength(2) + expect(sidecarMockData).toEqual([ + undefined, + { fieldA: 'updated A', fieldB: 'updated B' }, + ]) + + expect(nestedMockData).toHaveLength(2) + expect(nestedMockData).toEqual([ + undefined, + { fieldA: 'updated A', fieldB: 'updated B' }, + ]) + + const [sidecar, nested] = Array.from( + document.querySelectorAll('input') + ) + + expect(sidecar).toHaveValue('updated A') + expect(nested).toHaveValue('updated B') + }) + it('should support StrictMode', async () => { const initialData = { foo: 'bar' } const sidecarMockData = [] diff --git a/packages/dnb-eufemia/src/extensions/forms/Form/data-context/useData.tsx b/packages/dnb-eufemia/src/extensions/forms/Form/data-context/useData.tsx index 0ed23c8c7cf..b80836d3a24 100644 --- a/packages/dnb-eufemia/src/extensions/forms/Form/data-context/useData.tsx +++ b/packages/dnb-eufemia/src/extensions/forms/Form/data-context/useData.tsx @@ -87,7 +87,7 @@ export default function useData( pointer.set(existingData, path, newValue) // update provider - sharedDataRef.current.update(existingData) + sharedDataRef.current.extend(existingData) }, [] ) diff --git a/packages/dnb-eufemia/src/shared/helpers/useSharedState.tsx b/packages/dnb-eufemia/src/shared/helpers/useSharedState.tsx index 4d4d5a99174..c5ff893fca4 100644 --- a/packages/dnb-eufemia/src/shared/helpers/useSharedState.tsx +++ b/packages/dnb-eufemia/src/shared/helpers/useSharedState.tsx @@ -39,7 +39,7 @@ export function useSharedState( } }, [hasMounted]) - useLayoutEffect(() => { + useEffect(() => { if (waitForMountedRef.current) { forceUpdate() } @@ -155,11 +155,6 @@ export function createSharedState( const get = () => sharedStates[id].data - const extend = (newData: Data) => { - sharedStates[id].data = { ...sharedStates[id].data, ...newData } - subscribers.forEach((subscriber) => subscriber()) - } - const set = (newData: Partial) => { sharedStates[id].data = { ...newData } } @@ -169,8 +164,15 @@ export function createSharedState( subscribers.forEach((subscriber) => subscriber()) } + const extend = (newData: Data) => { + sharedStates[id].data = { ...sharedStates[id].data, ...newData } + subscribers.forEach((subscriber) => subscriber()) + } + const subscribe = (subscriber: Subscriber) => { - subscribers.push(subscriber) + if (!subscribers.includes(subscriber)) { + subscribers.push(subscriber) + } } const unsubscribe = (subscriber: Subscriber) => {