Skip to content

Commit 5f452c0

Browse files
committed
fix(react-bindings): multiple client async start handling while loading
1 parent e674819 commit 5f452c0

File tree

3 files changed

+27
-17
lines changed

3 files changed

+27
-17
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useMemo, useRef, useState } from 'react';
1+
import { useEffect, useRef, useState } from 'react';
22

33
import { Log, StatsigUser, _getInstance } from '@statsig/client-core';
44
import { StatsigClient, StatsigOptions } from '@statsig/js-client';
@@ -14,24 +14,25 @@ export function useStatsigInternalClientFactoryAsync<T extends StatsigClient>(
1414
args: FactoryArgs,
1515
): { isLoading: boolean; client: T } {
1616
const [isLoading, setIsLoading] = useState(true);
17-
const clientRef = useRef<T | null>(_getInstance(args.sdkKey) as T | null);
18-
19-
const client = useMemo(() => {
20-
if (clientRef.current) {
21-
return clientRef.current;
17+
const clientRef = useRef<T>(
18+
(_getInstance(args.sdkKey) as T | null) ?? factory(args),
19+
);
20+
21+
useEffect(() => {
22+
// already initializing or initialized
23+
if (clientRef.current.loadingStatus !== 'Uninitialized') {
24+
setIsLoading(false);
25+
return;
2226
}
2327

24-
const inst = factory(args);
25-
26-
clientRef.current = inst;
27-
28-
inst
28+
clientRef.current
2929
.initializeAsync()
3030
.catch(Log.error)
3131
.finally(() => setIsLoading(false));
32-
33-
return inst;
3432
}, []);
3533

36-
return { client, isLoading };
34+
return {
35+
client: clientRef.current,
36+
isLoading,
37+
};
3738
}

samples/react/src/__tests__/HomePage.test.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { render, waitFor } from '@testing-library/react';
22
import fetchMock from 'jest-fetch-mock';
3+
import { StrictMode } from 'react';
34
import { InitResponse } from 'statsig-test-helpers';
45

56
import HomePage from '../HomePage';
@@ -10,7 +11,11 @@ describe('App', () => {
1011
});
1112

1213
it('renders the Passing value', async () => {
13-
const { getByText } = render(<HomePage />);
14+
const { getByText } = render(
15+
<StrictMode>
16+
<HomePage />
17+
</StrictMode>,
18+
);
1419

1520
const result = await waitFor(() => getByText('Passing'));
1621
expect(result).toBeDefined();

samples/react/src/main.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import '@fontsource/roboto/400.css';
33
import '@fontsource/roboto/500.css';
44
import '@fontsource/roboto/700.css';
55
import { Box } from '@mui/material';
6-
import { ReactNode, lazy } from 'react';
6+
import { ReactNode, StrictMode, lazy } from 'react';
77
import * as ReactDOM from 'react-dom/client';
88
import {
99
RouteObject,
@@ -89,4 +89,8 @@ function App() {
8989
);
9090
}
9191

92-
root.render(<App />);
92+
root.render(
93+
<StrictMode>
94+
<App />
95+
</StrictMode>,
96+
);

0 commit comments

Comments
 (0)