Skip to content

Commit 07cceca

Browse files
fixed useSplitClient to support changes on update options
1 parent d3def5b commit 07cceca

2 files changed

Lines changed: 52 additions & 27 deletions

File tree

src/__tests__/useSplitClient.test.tsx

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { useSplitClient } from '../useSplitClient';
1515
import { SplitClient } from '../SplitClient';
1616
import { SplitContext } from '../SplitContext';
1717

18-
test('useSplitClient', () => {
18+
test('useSplitClient must update on SDK events', () => {
1919
const outerFactory = SplitSdk(sdkBrowser);
2020
const mainClient = outerFactory.client() as any;
2121
const user2Client = outerFactory.client('user_2') as any;
@@ -128,3 +128,40 @@ test('useSplitClient', () => {
128128

129129
expect(countNestedComponent).toEqual(4);
130130
});
131+
132+
test('useSplitClient must support changes in update props', () => {
133+
const outerFactory = SplitSdk(sdkBrowser);
134+
const mainClient = outerFactory.client() as any;
135+
136+
let rendersCount = 0;
137+
138+
function InnerComponent(updateOptions) {
139+
useSplitClient(undefined, undefined, undefined, updateOptions);
140+
rendersCount++;
141+
return null;
142+
}
143+
144+
function Component(updateOptions) {
145+
return (
146+
<SplitFactory factory={outerFactory} >
147+
<InnerComponent {...updateOptions} />
148+
</SplitFactory>
149+
)
150+
}
151+
152+
const wrapper = render(<Component />);
153+
154+
act(() => mainClient.__emitter__.emit(Event.SDK_READY)); // trigger re-render
155+
act(() => mainClient.__emitter__.emit(Event.SDK_UPDATE)); // do not trigger re-render because updateOnSdkUpdate is false by default
156+
expect(rendersCount).toBe(2);
157+
158+
wrapper.rerender(<Component updateOnSdkUpdate={true} />); // trigger re-render
159+
act(() => mainClient.__emitter__.emit(Event.SDK_UPDATE)); // trigger re-render because updateOnSdkUpdate is true now
160+
161+
expect(rendersCount).toBe(4);
162+
163+
wrapper.rerender(<Component updateOnSdkUpdate={false} />); // trigger re-render
164+
act(() => mainClient.__emitter__.emit(Event.SDK_UPDATE)); // do not trigger re-render because updateOnSdkUpdate is false now
165+
166+
expect(rendersCount).toBe(5);
167+
});

src/useSplitClient.ts

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ const DEFAULT_OPTIONS = {
1717
* @return A Split Context object
1818
* @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#advanced-instantiate-multiple-sdk-clients}
1919
*/
20-
export function useSplitClient(key?: SplitIO.SplitKey, trafficType?: string, attributes?: SplitIO.Attributes, options: IUpdateProps = {}): ISplitContextValues {
21-
options = { ...DEFAULT_OPTIONS, ...options };
20+
export function useSplitClient(key?: SplitIO.SplitKey, trafficType?: string, attributes?: SplitIO.Attributes, options?: IUpdateProps): ISplitContextValues {
21+
const {
22+
updateOnSdkReady, updateOnSdkReadyFromCache, updateOnSdkTimedout, updateOnSdkUpdate
23+
} = { ...DEFAULT_OPTIONS, ...options };
2224

2325
const context = React.useContext(SplitContext);
2426
const { client: contextClient, factory } = context;
@@ -35,37 +37,23 @@ export function useSplitClient(key?: SplitIO.SplitKey, trafficType?: string, att
3537
React.useEffect(() => {
3638
if (!client) return;
3739

38-
const setReady = () => {
39-
if (options.updateOnSdkReady) setLastUpdate(client.lastUpdate);
40-
}
41-
42-
const setReadyFromCache = () => {
43-
if (options.updateOnSdkReadyFromCache) setLastUpdate(client.lastUpdate);
44-
}
45-
46-
const setTimedout = () => {
47-
if (options.updateOnSdkTimedout) setLastUpdate(client.lastUpdate);
48-
}
49-
50-
const setUpdate = () => {
51-
if (options.updateOnSdkUpdate) setLastUpdate(client.lastUpdate);
52-
}
40+
const update = () => setLastUpdate(client.lastUpdate);
5341

5442
// Subscribe to SDK events
5543
const status = getStatus(client);
56-
if (!status.isReady) client.once(client.Event.SDK_READY, setReady);
57-
if (!status.isReadyFromCache) client.once(client.Event.SDK_READY_FROM_CACHE, setReadyFromCache);
58-
if (!status.hasTimedout && !status.isReady) client.once(client.Event.SDK_READY_TIMED_OUT, setTimedout);
59-
client.on(client.Event.SDK_UPDATE, setUpdate);
44+
if (!status.isReady && updateOnSdkReady) client.once(client.Event.SDK_READY, update);
45+
if (!status.isReadyFromCache && updateOnSdkReadyFromCache) client.once(client.Event.SDK_READY_FROM_CACHE, update);
46+
if (!status.hasTimedout && !status.isReady && updateOnSdkTimedout) client.once(client.Event.SDK_READY_TIMED_OUT, update);
47+
if (updateOnSdkUpdate) client.on(client.Event.SDK_UPDATE, update);
6048

6149
return () => {
6250
// Unsubscribe from events
63-
client.off(client.Event.SDK_READY, setReady);
64-
client.off(client.Event.SDK_READY_FROM_CACHE, setReadyFromCache);
65-
client.off(client.Event.SDK_READY_TIMED_OUT, setTimedout);
66-
client.off(client.Event.SDK_UPDATE, setUpdate);
51+
client.off(client.Event.SDK_READY, update);
52+
client.off(client.Event.SDK_READY_FROM_CACHE, update);
53+
client.off(client.Event.SDK_READY_TIMED_OUT, update);
54+
client.off(client.Event.SDK_UPDATE, update);
6755
}
68-
}, [client]);
56+
}, [client, updateOnSdkReady, updateOnSdkReadyFromCache, updateOnSdkTimedout, updateOnSdkUpdate]);
6957

7058
return {
7159
factory, client, ...getStatus(client)

0 commit comments

Comments
 (0)