Skip to content

Commit

Permalink
Merge pull request #168 from splitio/flagSets
Browse files Browse the repository at this point in the history
Add `flagSets` prop to `SplitTreatments` component and `useSplitTreatments` hook
  • Loading branch information
EmilianoSanchez authored Nov 15, 2023
2 parents 1424ab3 + 263ee5c commit 45c9b7e
Show file tree
Hide file tree
Showing 11 changed files with 218 additions and 140 deletions.
9 changes: 6 additions & 3 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
1.10.0 (November XX, 2023)
1.10.0 (November 16, 2023)
- Added support for Flag Sets on the SDK, which enables grouping feature flags and interacting with the group rather than individually (more details in our documentation):
- Added a new `flagSets` prop to the `SplitTreatments` component and `flagSets` option to the `useSplitTreatments` hook options object, to support evaluating flags in given flag set/s. Either `names` or `flagSets` must be provided to the component and hook. If both are provided, `names` will be used.
- Added a new optional Split Filter configuration option. This allows the SDK and Split services to only synchronize the flags in the specified flag sets, avoiding unused or unwanted flags from being synced on the SDK instance, bringing all the benefits from a reduced payload.
- Added `sets` property to the `SplitView` object returned by the `split` and `splits` methods of the SDK manager to expose flag sets on flag views.
- Added new `useSplitClient`, `useSplitTreatments` and `useSplitManager` hooks as replacements for the now deprecated `useClient`, `useTreatments` and `useManager` hooks.
- These new hooks return the Split context object along with the SDK client, treatments and manager respectively, enabling direct access to status properties like `isReady`, eliminating the need for using the `useContext` hook or the client's `ready` promise.
- `useSplitClient` and `useSplitTreatments` accept an options object as parameter, which support the same arguments as their predecessors, with additional boolean options for controlling re-rendering: `updateOnSdkReady`, `updateOnSdkReadyFromCache`, `updateOnSdkTimedout`, and `updateOnSdkUpdate`.
- `useSplitTreatments` optimizes feature flag evaluations by using the `useMemo` hook to memoize `getTreatmentsWithConfig` method calls from the SDK. This avoids re-evaluating feature flags when the hook is called with the same options and the feature flag definitions have not changed.
- They fixed a bug in the deprecated `useClient` and `useTreatments` hooks, which caused them to not re-render and re-evaluate feature flags when they access a different SDK client than the context and its status updates (i.e., when it emits SDK_READY or other event).
- Added TypeScript types and interfaces to the library index exports, allowing them to be imported, e.g., `import type { ISplitFactoryProps } from '@splitsoftware/splitio-react'` (Related to issue https://github.com/splitio/react-client/issues/162).
- Added TypeScript types and interfaces to the library index exports, allowing them to be imported from the library index, e.g., `import type { ISplitFactoryProps } from '@splitsoftware/splitio-react'` (Related to issue https://github.com/splitio/react-client/issues/162).
- Updated type declarations of the library components to not restrict the type of the `children` prop to ReactElement, allowing to pass any valid ReactNode value (Related to issue https://github.com/splitio/react-client/issues/164).
- Updated the `useTreatments` hook to optimize feature flag evaluations.
- Updated linter and other dependencies for vulnerability fixes.
- Bugfixing - Removed conditional code within hooks to adhere to the rules of hooks and prevent React warnings. Previously, this code checked for the availability of the hooks API (available in React version 16.8.0 or above) and logged an error message. Now, using hooks with React versions below 16.8.0 will throw an error.
- Bugfixing - Updated `useClient` and `useTreatments` hooks to re-render and re-evaluate feature flags when they consume a different SDK client than the context and its status updates (i.e., when it emits SDK_READY or other event).
Expand Down
34 changes: 17 additions & 17 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.9.1-rc.0",
"version": "1.10.0",
"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.23.0",
"@splitsoftware/splitio": "10.24.0-beta",
"memoize-one": "^5.1.1",
"shallowequal": "^1.1.0"
},
Expand Down
23 changes: 8 additions & 15 deletions src/SplitTreatments.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React from 'react';
import { SplitContext } from './SplitContext';
import { ISplitTreatmentsProps, ISplitContextValues } from './types';
import { getControlTreatmentsWithConfig, WARN_ST_NO_CLIENT } from './constants';
import { WARN_ST_NO_CLIENT } from './constants';
import { memoizeGetTreatmentsWithConfig } from './utils';

/**
* SplitTreatments accepts a list of feature flag names and optional attributes. It access the client at SplitContext to
* call 'client.getTreatmentsWithConfig()' method, and passes the returned treatments to a child as a function.
* SplitTreatments accepts a list of feature flag names and optional attributes. It accesses the client at SplitContext to
* call the 'client.getTreatmentsWithConfig()' method if the `names` prop is provided, or the 'client.getTreatmentsWithConfigByFlagSets()' method
* if the `flagSets` prop is provided. It then passes the resulting treatments to a child component as a function.
*
* @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#get-treatments-with-configurations}
*/
Expand All @@ -18,22 +19,14 @@ export class SplitTreatments extends React.Component<ISplitTreatmentsProps> {
private evaluateFeatureFlags = memoizeGetTreatmentsWithConfig();

render() {
const { names, children, attributes } = this.props;
const { names, flagSets, children, attributes } = this.props;

return (
<SplitContext.Consumer>
{(splitContext: ISplitContextValues) => {
const { client, isReady, isReadyFromCache, isDestroyed, lastUpdate } = splitContext;
let treatments;
const isOperational = !isDestroyed && (isReady || isReadyFromCache);
if (client && isOperational) {
// Cloning `client.getAttributes` result for memoization, because it returns the same reference unless `client.clearAttributes` is called.
// Caveat: same issue happens with `names` and `attributes` props if the user follows the bad practice of mutating the object instead of providing a new one.
treatments = this.evaluateFeatureFlags(client, lastUpdate, names, attributes, { ...client.getAttributes() });
} else {
treatments = getControlTreatmentsWithConfig(names);
if (!client) { this.logWarning = true; }
}
const { client, lastUpdate } = splitContext;
const treatments = this.evaluateFeatureFlags(client, lastUpdate, names, attributes, client ? { ...client.getAttributes() } : {}, flagSets);
if (!client) { this.logWarning = true; }
// SplitTreatments only accepts a function as a child, not a React Element (JSX)
return children({
...splitContext, treatments,
Expand Down
Loading

0 comments on commit 45c9b7e

Please sign in to comment.