Skip to content

Commit f656a1e

Browse files
added useTreatmentsAndContext and useClientAndContext hooks, for internal usage at the moment
1 parent 1d34d39 commit f656a1e

14 files changed

Lines changed: 90 additions & 34 deletions

src/SplitContext.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@ import { EXCEPTION_NO_REACT_OR_CREATECONTEXT } from './constants';
44

55
if (!React || !React.createContext) throw new Error(EXCEPTION_NO_REACT_OR_CREATECONTEXT);
66

7-
/**
8-
* Split Context is the React Context instance that represents our SplitIO global state.
9-
* It contains Split SDK objects, such as a factory instance, a client and its status (isReady, isTimedout, lastUpdate)
10-
* The context is created with default empty values, that eventually SplitFactory and SplitClient access and update.
11-
*/
12-
const SplitContext = React.createContext<ISplitContextValues>({
7+
export const INITIAL_CONTEXT: ISplitContextValues = {
138
client: null,
149
factory: null,
1510
isReady: false,
@@ -18,7 +13,14 @@ const SplitContext = React.createContext<ISplitContextValues>({
1813
hasTimedout: false,
1914
lastUpdate: 0,
2015
isDestroyed: false,
21-
});
16+
}
17+
18+
/**
19+
* Split Context is the React Context instance that represents our SplitIO global state.
20+
* It contains Split SDK objects, such as a factory instance, a client and its status (isReady, isTimedout, lastUpdate)
21+
* The context is created with default empty values, that eventually SplitFactory and SplitClient access and update.
22+
*/
23+
const SplitContext = React.createContext<ISplitContextValues>(INITIAL_CONTEXT);
2224

2325
export default SplitContext;
2426
export { ISplitContextValues };

src/useClient.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
1-
import React from 'react';
2-
import SplitContext from './SplitContext';
3-
import { ERROR_UC_NO_USECONTEXT } from './constants';
4-
import { getSplitSharedClient, checkHooks, initAttributes } from './utils';
1+
import { useClientAndContext } from './useClientAndContext';
52

63
/**
7-
* 'useClient' is a custom hook that returns a client from the Split context.
4+
* 'useClient' is a hook that returns a client from the Split context.
85
* It uses the 'useContext' hook to access the context, which is updated by
96
* SplitFactory and SplitClient components in the hierarchy of components.
107
*
118
* @return A Split Client instance, or null if used outside the scope of SplitFactory
129
* @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#advanced-instantiate-multiple-sdk-clients}
1310
*/
1411
const useClient = (key?: SplitIO.SplitKey, trafficType?: string, attributes?: SplitIO.Attributes): SplitIO.IBrowserClient | null => {
15-
if (!checkHooks(ERROR_UC_NO_USECONTEXT)) return null;
16-
// eslint-disable-next-line prefer-const
17-
let { factory, client } = React.useContext(SplitContext);
18-
if (key && factory) {
19-
client = getSplitSharedClient(factory, key, trafficType, attributes);
20-
}
21-
if (client) initAttributes(client, attributes);
22-
return client;
12+
return useClientAndContext(key, trafficType, attributes).client;
2313
};
2414

2515
export default useClient;

src/useClientAndContext.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react';
2+
import SplitContext, { ISplitContextValues, INITIAL_CONTEXT } from './SplitContext';
3+
import { ERROR_UC_NO_USECONTEXT } from './constants';
4+
import { getSplitSharedClient, checkHooks, initAttributes, IClientWithContext } from './utils';
5+
6+
/**
7+
* 'useClientAndContext' is a hook that returns an Split Context object with the client and its status corresponding to the provided key and trafficType.
8+
* It uses the 'useContext' hook to access the context, which is updated by SplitFactory and SplitClient components in the hierarchy of components.
9+
*
10+
* @return A Split Context object
11+
* @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#advanced-instantiate-multiple-sdk-clients}
12+
*/
13+
export function useClientAndContext(key?: SplitIO.SplitKey, trafficType?: string, attributes?: SplitIO.Attributes): ISplitContextValues {
14+
if (!checkHooks(ERROR_UC_NO_USECONTEXT)) return INITIAL_CONTEXT;
15+
16+
const context = React.useContext(SplitContext); // eslint-disable-next-line prefer-const
17+
let { factory, client } = context;
18+
if (key && factory) {
19+
client = getSplitSharedClient(factory, key, trafficType, attributes);
20+
}
21+
if (client) initAttributes(client, attributes);
22+
return client === context.client ? context : {
23+
...context, client, ...(client as IClientWithContext).__getStatus()
24+
};
25+
}

src/useManager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ERROR_UM_NO_USECONTEXT } from './constants';
44
import { checkHooks } from './utils';
55

66
/**
7-
* 'useManager' is a custom hook that returns the Manager instance from the Split factory.
7+
* 'useManager' is a hook that returns the Manager instance from the Split factory.
88
* It uses the 'useContext' hook to access the factory at Split context, which is updated by
99
* the SplitFactory component.
1010
*

src/useTrack.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { checkHooks } from './utils';
66
const noOpFalse = () => false;
77

88
/**
9-
* 'useTrack' is a custom hook that returns the track method from a Split client.
9+
* 'useTrack' is a hook that returns the track method from a Split client.
1010
* It uses the 'useContext' hook to access the client from the Split context.
1111
*
1212
* @return A track function binded to a Split client. If the client is not available, the result is a no-op function that returns false.

src/useTreatments.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
1-
import useClient from './useClient';
2-
import { getControlTreatmentsWithConfig, ERROR_UT_NO_USECONTEXT } from './constants';
3-
import { checkHooks, IClientWithContext } from './utils';
1+
import { useTreatmentsAndContext } from './useTreatmentsAndContext';
42

53
/**
6-
* 'useTreatments' is a custom hook that returns a list of treatments.
4+
* 'useTreatments' is a hook that returns an object of feature flag evaluations (i.e., treatments).
75
* It uses the 'useContext' hook to access the client from the Split context,
86
* and invokes the 'getTreatmentsWithConfig' method.
97
*
108
* @return A TreatmentsWithConfig instance, that might contain control treatments if the client is not available or ready, or if split names do not exist.
119
* @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#get-treatments-with-configurations}
1210
*/
1311
const useTreatments = (splitNames: string[], attributes?: SplitIO.Attributes, key?: SplitIO.SplitKey): SplitIO.TreatmentsWithConfig => {
14-
const client = checkHooks(ERROR_UT_NO_USECONTEXT) ? useClient(key) : null;
15-
return client && (client as IClientWithContext).__getStatus().isOperational ?
16-
client.getTreatmentsWithConfig(splitNames, attributes) :
17-
getControlTreatmentsWithConfig(splitNames);
12+
return useTreatmentsAndContext(splitNames, attributes, key).treatments;
1813
};
1914

2015
export default useTreatments;

src/useTreatmentsAndContext.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { getControlTreatmentsWithConfig, ERROR_UT_NO_USECONTEXT } from './constants';
2+
import { checkHooks, IClientWithContext } from './utils';
3+
import { ISplitTreatmentsChildProps } from './types';
4+
import { INITIAL_CONTEXT } from './SplitContext';
5+
import { useClientAndContext } from './useClientAndContext';
6+
7+
/**
8+
* 'useTreatmentsAndContext' is a hook that returns an SplitContext object extended with a `treatments` property containing an object of feature flag evaluations (i.e., treatments).
9+
* It uses the 'useClientAndContext' hook to access the client from the Split context, and invokes the 'getTreatmentsWithConfig' method.
10+
*
11+
* @return A Split Context object extended with a TreatmentsWithConfig instance, that might contain control treatments if the client is not available or ready, or if split names do not exist.
12+
* @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#get-treatments-with-configurations}
13+
*/
14+
export function useTreatmentsAndContext(splitNames: string[], attributes?: SplitIO.Attributes, key?: SplitIO.SplitKey): ISplitTreatmentsChildProps {
15+
const context = checkHooks(ERROR_UT_NO_USECONTEXT) ? useClientAndContext(key) : INITIAL_CONTEXT;
16+
const client = context.client;
17+
const treatments = client && (client as IClientWithContext).__getStatus().isOperational ?
18+
client.getTreatmentsWithConfig(splitNames, attributes) :
19+
getControlTreatmentsWithConfig(splitNames);
20+
21+
return {
22+
...context,
23+
treatments,
24+
};
25+
}

types/SplitContext.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import { ISplitContextValues } from './types';
3+
export declare const INITIAL_CONTEXT: ISplitContextValues;
34
/**
45
* Split Context is the React Context instance that represents our SplitIO global state.
56
* It contains Split SDK objects, such as a factory instance, a client and its status (isReady, isTimedout, lastUpdate)

types/useClient.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* 'useClient' is a custom hook that returns a client from the Split context.
2+
* 'useClient' is a hook that returns a client from the Split context.
33
* It uses the 'useContext' hook to access the context, which is updated by
44
* SplitFactory and SplitClient components in the hierarchy of components.
55
*

types/useClientAndContext.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { ISplitContextValues } from './SplitContext';
2+
/**
3+
* 'useClientAndContext' is a hook that returns an Split Context object with the client and its status corresponding to the provided key and trafficType.
4+
* It uses the 'useContext' hook to access the context, which is updated by SplitFactory and SplitClient components in the hierarchy of components.
5+
*
6+
* @return A Split Context object
7+
* @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#advanced-instantiate-multiple-sdk-clients}
8+
*/
9+
export declare function useClientAndContext(key?: SplitIO.SplitKey, trafficType?: string, attributes?: SplitIO.Attributes): ISplitContextValues;

0 commit comments

Comments
 (0)