From f5f59d3446082594bcfad3e156a6d76a43114cc9 Mon Sep 17 00:00:00 2001 From: Mitsuyuki Shiiba Date: Wed, 14 Feb 2024 19:44:58 +0900 Subject: [PATCH 1/4] Modify Provider to keep the latest flags even when it is remounted --- src/asyncWithLDProvider.test.tsx | 31 +++++++++++++++++++++++++++++++ src/asyncWithLDProvider.tsx | 6 ++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/asyncWithLDProvider.test.tsx b/src/asyncWithLDProvider.test.tsx index 48e9de7..c1f4ece 100644 --- a/src/asyncWithLDProvider.test.tsx +++ b/src/asyncWithLDProvider.test.tsx @@ -227,4 +227,35 @@ describe('asyncWithLDProvider', () => { expect(receivedNode).toHaveTextContent('{"testFlag":false}'); }); + + test('Provider keeps the latest flags even when it is remounted', async () => { + mockInitLDClient.mockImplementation(() => ({ + ldClient: mockLDClient, + flags: rawFlags, + })); + + mockLDClient.on.mockImplementationOnce((e: string, cb: (c: LDFlagChangeset) => void) => { + cb({ 'test-flag': { current: false, previous: true }, 'another-test-flag': { current: false, previous: true } }); + }); + const options: LDOptions = {}; + + const LDProvider = await asyncWithLDProvider({ clientSideID, context, options }); + + const { getByText: getByText1, unmount } = render( + + {(value) => Received: {JSON.stringify(value.flags)}} + , + ); + const receivedNode1 = getByText1(/^Received:/); + expect(receivedNode1).toHaveTextContent('{"testFlag":false,"anotherTestFlag":false}'); + unmount(); + + const { getByText: getByText2 } = render( + + {(value) => Received: {JSON.stringify(value.flags)}} + , + ); + const receivedNode2 = getByText2(/^Received:/); + expect(receivedNode2).toHaveTextContent('{"testFlag":false,"anotherTestFlag":false}'); + }); }); diff --git a/src/asyncWithLDProvider.tsx b/src/asyncWithLDProvider.tsx index 3b28ec4..dea1df1 100644 --- a/src/asyncWithLDProvider.tsx +++ b/src/asyncWithLDProvider.tsx @@ -41,11 +41,12 @@ export default async function asyncWithLDProvider(config: AsyncProviderConfig) { ); const initialFlags = options?.bootstrap && options.bootstrap !== 'localStorage' ? options.bootstrap : fetchedFlags; + let currentFlags = initialFlags; const LDProvider = ({ children }: { children: ReactNode }) => { const [ldData, setLDData] = useState(() => ({ - unproxiedFlags: initialFlags, - ...getFlagsProxy(ldClient, initialFlags, reactOptions, targetFlags), + unproxiedFlags: currentFlags, + ...getFlagsProxy(ldClient, currentFlags, reactOptions, targetFlags), })); useEffect(() => { @@ -54,6 +55,7 @@ export default async function asyncWithLDProvider(config: AsyncProviderConfig) { if (Object.keys(updates).length > 0) { setLDData(({ unproxiedFlags }) => { const updatedUnproxiedFlags = { ...unproxiedFlags, ...updates }; + currentFlags = updatedUnproxiedFlags; return { unproxiedFlags: updatedUnproxiedFlags, From eac2c2466a52dde418c6d40e8b0b69ce08b3c85b Mon Sep 17 00:00:00 2001 From: Mitz Date: Sat, 16 Mar 2024 08:02:51 +0900 Subject: [PATCH 2/4] Remove empty lines. Co-authored-by: Yusinto Ngadiman --- src/asyncWithLDProvider.test.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/asyncWithLDProvider.test.tsx b/src/asyncWithLDProvider.test.tsx index c1f4ece..d9267d7 100644 --- a/src/asyncWithLDProvider.test.tsx +++ b/src/asyncWithLDProvider.test.tsx @@ -233,12 +233,10 @@ describe('asyncWithLDProvider', () => { ldClient: mockLDClient, flags: rawFlags, })); - mockLDClient.on.mockImplementationOnce((e: string, cb: (c: LDFlagChangeset) => void) => { cb({ 'test-flag': { current: false, previous: true }, 'another-test-flag': { current: false, previous: true } }); }); const options: LDOptions = {}; - const LDProvider = await asyncWithLDProvider({ clientSideID, context, options }); const { getByText: getByText1, unmount } = render( From 1456bb3af77d1249f956f767646e5ec8a75df050 Mon Sep 17 00:00:00 2001 From: Mitz Date: Sat, 16 Mar 2024 08:06:47 +0900 Subject: [PATCH 3/4] Update src/asyncWithLDProvider.test.tsx Co-authored-by: Yusinto Ngadiman --- src/asyncWithLDProvider.test.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/asyncWithLDProvider.test.tsx b/src/asyncWithLDProvider.test.tsx index d9267d7..aaa9bef 100644 --- a/src/asyncWithLDProvider.test.tsx +++ b/src/asyncWithLDProvider.test.tsx @@ -239,21 +239,19 @@ describe('asyncWithLDProvider', () => { const options: LDOptions = {}; const LDProvider = await asyncWithLDProvider({ clientSideID, context, options }); - const { getByText: getByText1, unmount } = render( + const { unmount } = render( {(value) => Received: {JSON.stringify(value.flags)}} , ); - const receivedNode1 = getByText1(/^Received:/); - expect(receivedNode1).toHaveTextContent('{"testFlag":false,"anotherTestFlag":false}'); unmount(); - - const { getByText: getByText2 } = render( + const { getByText } = render( {(value) => Received: {JSON.stringify(value.flags)}} , ); - const receivedNode2 = getByText2(/^Received:/); - expect(receivedNode2).toHaveTextContent('{"testFlag":false,"anotherTestFlag":false}'); + const receivedNode = getByText(/^Received:/); + + expect(receivedNode).toHaveTextContent('{"testFlag":false,"anotherTestFlag":false}'); }); }); From 675931e05af815afda6ead92d2ae94eea32db2b4 Mon Sep 17 00:00:00 2001 From: Mitsuyuki Shiiba Date: Sat, 16 Mar 2024 08:14:14 +0900 Subject: [PATCH 4/4] Remove redundant variables --- src/asyncWithLDProvider.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/asyncWithLDProvider.tsx b/src/asyncWithLDProvider.tsx index dea1df1..2d380e5 100644 --- a/src/asyncWithLDProvider.tsx +++ b/src/asyncWithLDProvider.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, ReactNode } from 'react'; +import React, { ReactNode, useEffect, useState } from 'react'; import { LDFlagChangeset } from 'launchdarkly-js-client-sdk'; import { AsyncProviderConfig, defaultReactOptions } from './types'; import { Provider } from './context'; @@ -40,8 +40,7 @@ export default async function asyncWithLDProvider(config: AsyncProviderConfig) { targetFlags, ); - const initialFlags = options?.bootstrap && options.bootstrap !== 'localStorage' ? options.bootstrap : fetchedFlags; - let currentFlags = initialFlags; + let currentFlags = options?.bootstrap && options.bootstrap !== 'localStorage' ? options.bootstrap : fetchedFlags; const LDProvider = ({ children }: { children: ReactNode }) => { const [ldData, setLDData] = useState(() => ({ @@ -54,12 +53,11 @@ export default async function asyncWithLDProvider(config: AsyncProviderConfig) { const updates = getFlattenedFlagsFromChangeset(changes, targetFlags); if (Object.keys(updates).length > 0) { setLDData(({ unproxiedFlags }) => { - const updatedUnproxiedFlags = { ...unproxiedFlags, ...updates }; - currentFlags = updatedUnproxiedFlags; + currentFlags = { ...unproxiedFlags, ...updates }; return { - unproxiedFlags: updatedUnproxiedFlags, - ...getFlagsProxy(ldClient, updatedUnproxiedFlags, reactOptions, targetFlags), + unproxiedFlags: currentFlags, + ...getFlagsProxy(ldClient, currentFlags, reactOptions, targetFlags), }; }); }