@splitsoftware/splitio-react
Version:
A React library to easily integrate and use Split JS SDK
61 lines (60 loc) • 4.41 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.SplitFactoryProvider = void 0;
var tslib_1 = require("tslib");
var React = (0, tslib_1.__importStar)(require("react"));
var constants_1 = require("./constants");
var utils_1 = require("./utils");
var SplitContext_1 = require("./SplitContext");
var client_1 = require("@splitsoftware/splitio/client");
/**
* Implementation rationale:
* - Follows React rules: pure components & hooks, with side effects managed in `useEffect`.
* - The `factory` and `client` properties in the context are available from the initial render, rather than being set lazily in a `useEffect`, so that:
* - Hooks retrieve the correct values from the start; for example, `useTrack` accesses the client's `track` method rather than a no-op function (related to https://github.com/splitio/react-client/issues/198).
* - Hooks can support Suspense and Server components where `useEffect` is not called (related to https://github.com/splitio/react-client/issues/192).
* - Re-renders are avoided for child components that do not depend on the factory being ready (e.g., tracking events, updating attributes, or managing consent).
* - `SplitFactoryProvider` updates the context only when props change (`config` or `factory`) but not the state (e.g., client status), preventing unnecessary updates to child components and allowing them to control when to update independently.
* - For these reasons, and to reduce component tree depth, `SplitFactoryProvider` no longer wraps the child component in a `SplitClient` component and thus does not accept a child as a function.
*/
/**
* The SplitFactoryProvider is the top level component that provides the Split SDK factory to all child components via the Split Context.
* It accepts either an SDK `factory` instance or a `config` object as props to initialize a new SDK factory.
*
* NOTE: Either pass a `factory` instance or a `config` object as props. If both props are passed, the `config` prop 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 re-initializations.
*
* @see {@link https://developer.harness.io/docs/feature-management-experimentation/sdks-and-infrastructure/client-side-sdks/react-sdk/#2-instantiate-the-sdk-and-create-a-new-split-client}
*/
function SplitFactoryProvider(props) {
var config = props.config, propFactory = props.factory, attributes = props.attributes, _a = props.updateOnSdkReady, updateOnSdkReady = _a === void 0 ? true : _a, _b = props.updateOnSdkReadyFromCache, updateOnSdkReadyFromCache = _b === void 0 ? true : _b, _c = props.updateOnSdkTimedout, updateOnSdkTimedout = _c === void 0 ? true : _c, _d = props.updateOnSdkUpdate, updateOnSdkUpdate = _d === void 0 ? true : _d;
var factory = React.useMemo(function () {
return propFactory ?
propFactory :
config ?
// @ts-expect-error. 2nd param is not part of type definitions. Used to overwrite the SDK version and enable lazy init
(0, client_1.SplitFactory)(config, function (modules) {
modules.settings.version = constants_1.VERSION;
modules.lazyInit = true;
}) :
undefined;
}, [config, propFactory]);
var client = factory ? (0, utils_1.getSplitClient)(factory) : undefined;
(0, utils_1.initAttributes)(client, attributes);
// Effect to initialize and destroy the factory when config is provided
React.useEffect(function () {
if (propFactory) {
if (config)
console.log(constants_1.WARN_SF_CONFIG_AND_FACTORY);
return;
}
if (factory) {
factory.init && factory.init();
return function () {
factory.destroy();
};
}
}, [config, propFactory, factory]);
return (React.createElement(SplitContext_1.SplitContext.Provider, { value: (0, tslib_1.__assign)((0, tslib_1.__assign)({ factory: factory, client: client }, (0, utils_1.getStatus)(client)), { updateOnSdkReady: updateOnSdkReady, updateOnSdkReadyFromCache: updateOnSdkReadyFromCache, updateOnSdkTimedout: updateOnSdkTimedout, updateOnSdkUpdate: updateOnSdkUpdate }) }, props.children));
}
exports.SplitFactoryProvider = SplitFactoryProvider;
;