Skip to content

Commit

Permalink
Add new SplitFactoryProvider component and deprecate SplitFactory com…
Browse files Browse the repository at this point in the history
…ponent and withSplitFactory HOC
  • Loading branch information
EmilianoSanchez committed Jan 11, 2024
1 parent 65ad71c commit 326aa6d
Show file tree
Hide file tree
Showing 9 changed files with 515 additions and 32 deletions.
50 changes: 25 additions & 25 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@splitsoftware/splitio-react",
"version": "1.10.2",
"version": "1.10.3-rc.3",
"description": "A React library to easily integrate and use Split JS SDK",
"main": "lib/index.js",
"module": "es/index.js",
Expand Down Expand Up @@ -62,7 +62,7 @@
},
"homepage": "https://github.com/splitio/react-client#readme",
"dependencies": {
"@splitsoftware/splitio": "10.24.1",
"@splitsoftware/splitio": "10.25.1-rc.0",
"memoize-one": "^5.1.1",
"shallowequal": "^1.1.0"
},
Expand Down
2 changes: 2 additions & 0 deletions src/SplitFactory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { DEFAULT_UPDATE_OPTIONS } from './useSplitClient';
* even if the component is updated with a different config or factory prop.
*
* @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK}
*
* @deprecated Replace with the new `SplitFactoryProvider` component.
*/
export class SplitFactory extends React.Component<ISplitFactoryProps, { factory: SplitIO.IBrowserSDK | null, client: SplitIO.IBrowserClient | null }> {

Expand Down
74 changes: 74 additions & 0 deletions src/SplitFactoryProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React from 'react';

import { SplitComponent } from './SplitClient';
import { ISplitFactoryProps } from './types';
import { WARN_SF_CONFIG_AND_FACTORY } from './constants';
import { getSplitFactory, destroySplitFactory, IFactoryWithClients, getSplitClient, getStatus } from './utils';
import { DEFAULT_UPDATE_OPTIONS } from './useSplitClient';

/**
* SplitFactoryProvider will initialize the Split SDK and its main client when it is mounted, listen for its events in order to update the Split Context,
* and automatically shutdown and release resources when it is unmounted. SplitFactoryProvider must wrap other library components and functions
* since they access the Split Context and its elements (factory, clients, etc).
*
* NOTE: Either pass a factory instance or a config object. If both are passed, the config object will be ignored.
* Pass the same reference to the config or factory object rather than a new instance on each render, to avoid unnecessary props changes and SDK reinitializations.
*
* @see {@link https://help.split.io/hc/en-us/articles/360038825091-React-SDK#2-instantiate-the-sdk-and-create-a-new-split-client}
*/
export function SplitFactoryProvider(props: ISplitFactoryProps) {
let {
config, factory: propFactory,
updateOnSdkReady, updateOnSdkReadyFromCache, updateOnSdkTimedout, updateOnSdkUpdate
} = { ...DEFAULT_UPDATE_OPTIONS, ...props };

if (config && propFactory) {
console.log(WARN_SF_CONFIG_AND_FACTORY);
config = undefined;
}

const [stateFactory, setStateFactory] = React.useState(propFactory || null);
const factory = propFactory || stateFactory;
const client = factory ? getSplitClient(factory) : null;

React.useEffect(() => {
if (config) {
const factory = getSplitFactory(config);
const client = getSplitClient(factory);
const status = getStatus(client);

// Update state and unsubscribe from events when first event is emitted
const update = () => {
client.off(client.Event.SDK_READY, update);
client.off(client.Event.SDK_READY_FROM_CACHE, update);
client.off(client.Event.SDK_READY_TIMED_OUT, update);
client.off(client.Event.SDK_UPDATE, update);

setStateFactory(factory);
}

if (updateOnSdkReady) {
if (status.isReady) update();
else client.once(client.Event.SDK_READY, update);
}
if (updateOnSdkReadyFromCache) {
if (status.isReadyFromCache) update();
else client.once(client.Event.SDK_READY_FROM_CACHE, update);
}
if (updateOnSdkTimedout) {
if (status.hasTimedout) update();
else client.once(client.Event.SDK_READY_TIMED_OUT, update);
}
if (updateOnSdkUpdate) client.on(client.Event.SDK_UPDATE, update);

return () => {
// Factory destroy unsubscribes from events
destroySplitFactory(factory as IFactoryWithClients);
}
}
}, [config, updateOnSdkReady, updateOnSdkReadyFromCache, updateOnSdkTimedout, updateOnSdkUpdate]);

return (
<SplitComponent {...props} factory={factory} client={client} />
);
}
Loading

0 comments on commit 326aa6d

Please sign in to comment.