diff --git a/packages/react-bindings/src/useStatsigInternalClientFactoryAsync.ts b/packages/react-bindings/src/useStatsigInternalClientFactoryAsync.ts index 72d95505..c884a7cc 100644 --- a/packages/react-bindings/src/useStatsigInternalClientFactoryAsync.ts +++ b/packages/react-bindings/src/useStatsigInternalClientFactoryAsync.ts @@ -1,4 +1,4 @@ -import { useMemo, useRef, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { Log, StatsigUser, _getInstance } from '@statsig/client-core'; import { StatsigClient, StatsigOptions } from '@statsig/js-client'; @@ -14,24 +14,25 @@ export function useStatsigInternalClientFactoryAsync( args: FactoryArgs, ): { isLoading: boolean; client: T } { const [isLoading, setIsLoading] = useState(true); - const clientRef = useRef(_getInstance(args.sdkKey) as T | null); - - const client = useMemo(() => { - if (clientRef.current) { - return clientRef.current; + const clientRef = useRef( + (_getInstance(args.sdkKey) as T | null) ?? factory(args), + ); + + useEffect(() => { + // already initializing or initialized + if (clientRef.current.loadingStatus !== 'Uninitialized') { + setIsLoading(false); + return; } - const inst = factory(args); - - clientRef.current = inst; - - inst + clientRef.current .initializeAsync() .catch(Log.error) .finally(() => setIsLoading(false)); - - return inst; }, []); - return { client, isLoading }; + return { + client: clientRef.current, + isLoading, + }; } diff --git a/samples/react/src/__tests__/HomePage.test.tsx b/samples/react/src/__tests__/HomePage.test.tsx index 6e72edb4..0efbaf00 100644 --- a/samples/react/src/__tests__/HomePage.test.tsx +++ b/samples/react/src/__tests__/HomePage.test.tsx @@ -1,5 +1,6 @@ import { render, waitFor } from '@testing-library/react'; import fetchMock from 'jest-fetch-mock'; +import { StrictMode } from 'react'; import { InitResponse } from 'statsig-test-helpers'; import HomePage from '../HomePage'; @@ -10,7 +11,11 @@ describe('App', () => { }); it('renders the Passing value', async () => { - const { getByText } = render(); + const { getByText } = render( + + + , + ); const result = await waitFor(() => getByText('Passing')); expect(result).toBeDefined(); diff --git a/samples/react/src/main.tsx b/samples/react/src/main.tsx index e9d38353..19ab0705 100644 --- a/samples/react/src/main.tsx +++ b/samples/react/src/main.tsx @@ -3,7 +3,7 @@ import '@fontsource/roboto/400.css'; import '@fontsource/roboto/500.css'; import '@fontsource/roboto/700.css'; import { Box } from '@mui/material'; -import { ReactNode, lazy } from 'react'; +import { ReactNode, StrictMode, lazy } from 'react'; import * as ReactDOM from 'react-dom/client'; import { RouteObject, @@ -89,4 +89,8 @@ function App() { ); } -root.render(); +root.render( + + + , +);