Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flagSets prop to SplitTreatments component and useSplitTreatments hook #168

Merged
merged 18 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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