Skip to content

Commit 11e01ae

Browse files
Team's feedback: add MIGRATION-GUIDE.md file
1 parent 6105b3f commit 11e01ae

File tree

4 files changed

+89
-2
lines changed

4 files changed

+89
-2
lines changed

MIGRATION-GUIDE.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# React SDK v1.11.0: replace deprecated components with the new `SplitFactoryProvider` component
2+
3+
The `SplitFactory` and `withSplitFactory` components have been deprecated since React SDK v1.11.0, and will be removed on a future major release.
4+
5+
We recommend migrating to the new `SplitFactoryProvider` component instead. This component is a revised version of `SplitFactory` that properly handles SDK side effects (factory creation and destruction) within the React component lifecycle, resolving memory leak issues in React development mode, strict mode and server-side rendering, and also ensuring that the SDK is updated if `config` or `factory` props change.
6+
7+
Notable changes to consider when migrating:
8+
- `SplitFactoryProvider` utilizes the React Hooks API, requiring React 16.8.0 or later, while `SplitFactory` is compatible with React 16.3.0 or later.
9+
10+
- When using the `config` prop with `SplitFactoryProvider`, `factory` and `client` properties in `SplitContext` are `null` in the first render, until the context is updated when some event is emitted on the SDK main client (ready, ready from cache, timeout or update depending on the configuration of the `updateOn<Event>` props of the component). This differs from the previous behavior where `factory` and `client` were immediately available. Nonetheless, it is not recommended to use the `client` and `factory` properties directly as better alternatives are available. For example, use the `useTrack` and `useSplitTreatments` hooks rather than the client's `track` and `getTreatments` methods.
11+
12+
- Updating the `config` prop in `SplitFactoryProvider` reinitializes the SDK with the new configuration, while `SplitFactory` does not reinitialize the SDK. It is recommended to pass a reference to the configuration object (e.g., via a global variable, `useState`, or `useMemo`) rather than a new instance on each render, to avoid unnecessary reinitializations.
13+
14+
- Updating the `factory` prop in `SplitFactoryProvider` replaces the current SDK instance, unlike `SplitFactory` where it is ignored.
15+
16+
# React SDK v1.10.0: replace deprecated hooks with new ones
17+
18+
The `useClient`, `useTreatments` and `useManager` hooks have been deprecated since React SDK v1.10.0, and will be removed on a future major release.
19+
20+
We recommend migrating to the new versions `useSplitClient`, `useSplitTreatments` and `useSplitManager` respectively, which provide a more flexible API:
21+
22+
- They accept extra optional parameters, `updateOnSdkReady`, `updateOnSdkReadyFromCache`, `updateOnSdkTimedout` and `updateOnSdkUpdate`, which enable to control when the hook updates the component. For example, you can set `updateOnSdkReady` to `true`, which is `false` by default, to update the component when an `SDK_UPDATE` event is emitted. This is useful when you want to avoid unnecessary re-renders of your components.
23+
24+
- They return an object containing the SDK status properties. These properties are described in the ['Subscribe to events and changes' section](https://help.split.io/hc/en-us/articles/360038825091-React-SDK#subscribe-to-events-and-changes) and enable conditional rendering of components based on the SDK status, eliminating the need to access the Split context or using the client's `ready` promise or event listeners. For example, you can show a loading spinner while the SDK is not ready, and use the `treatments` result to render the variants of your App once the SDK is ready.
25+
26+
```js
27+
const { client, isReady, isReadyFromCache, hasTimedout, lastUpdate } = useSplitClient();
28+
const { treatments, isReady, isReadyFromCache, hasTimedout, lastUpdate } = useSplitTreatments({ names: ['feature-flag-1'] });
29+
const { manager, isReady, isReadyFromCache, hasTimedout, lastUpdate } = useSplitManager();
30+
```
31+
32+
33+
34+
To refactor your existing code, replace:
35+
36+
```javascript
37+
const client = useClient(optionalSplitKey, optionalTrafficType, optionalAttributes);
38+
const treatments = useTreatments(featureFlagNames, optionalAttributes, optionalSplitKey);
39+
const manager = useManager();
40+
```
41+
42+
with:
43+
44+
```javascript
45+
const { client } = useSplitClient({ splitKey: optionalSplitKey, trafficType: optionalTrafficType, attributes: optionalAttributes });
46+
const { treatments } = useSplitTreatments({ names: featureFlagNames, attributes: optionalAttributes, splitKey: optionalSplitKey });
47+
const { manager } = useSplitManager();
48+
```
49+
50+
and use the status properties to conditionally render your components. For example, do:
51+
52+
```javascript
53+
const MyComponent = ({ userId }) => {
54+
55+
const { treatments, isReady } = useSplitTreatments({ names: [FEATURE_X], splitKey: userId })
56+
57+
return isReady ?
58+
treatments[FEATURE_X].treatment === 'on' ?
59+
<FeatureOn /> :
60+
<FeatureOff /> :
61+
<LoadingPage />
62+
}
63+
```
64+
65+
instead of:
66+
67+
```javascript
68+
const MyComponent = ({ userId }) => {
69+
70+
const [sdkIsReady, setSdkIsReady] = useState(false);
71+
const client = useClient(userId);
72+
const treatments = useTreatments([FEATURE_X], undefined, userId);
73+
74+
useEffect(() => {
75+
if (client) client.ready().then(() => setSdkIsReady(true));
76+
}, [client]);
77+
78+
return isReady ?
79+
treatments[FEATURE_X].treatment === 'on' ?
80+
<FeatureOn /> :
81+
<FeatureOff /> :
82+
<LoadingPage />
83+
}
84+
```

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"files": [
99
"README.md",
1010
"CONTRIBUTORS-GUIDE.md",
11+
"MIGRATION-GUIDE.md",
1112
"LICENSE",
1213
"CHANGES.txt",
1314
"src",

src/SplitFactory.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import { DEFAULT_UPDATE_OPTIONS } from './useSplitClient';
1414
* The underlying SDK factory and client is set on the constructor, and cannot be changed during the component lifecycle,
1515
* even if the component is updated with a different config or factory prop.
1616
*
17-
* @deprecated Replace with the new `SplitFactoryProvider` component.
17+
* @deprecated `SplitFactory` will be removed in a future major release. We recommend replacing it with the new `SplitFactoryProvider` component.
18+
*
1819
* `SplitFactoryProvider` is a revised version of `SplitFactory` that properly handles SDK side effects (factory creation and destruction) within the React component lifecycle,
1920
* resolving memory leak issues in React development mode, strict mode and server-side rendering, and also ensuring that the SDK is updated if `config` or `factory` props change.
2021
*

src/withSplitFactory.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import { SplitFactory } from './SplitFactory';
1010
* @param config Config object used to instantiate a Split factory
1111
* @param factory Split factory instance to use instead of creating a new one with the config object.
1212
*
13-
* @deprecated Replace with the new `SplitFactoryProvider` component.
13+
* @deprecated `withSplitFactory` will be removed in a future major release. We recommend replacing it with the new `SplitFactoryProvider` component.
14+
*
1415
* `SplitFactoryProvider` is a revised version of `SplitFactory` that properly handles SDK side effects (factory creation and destruction) within the React component lifecycle,
1516
* resolving memory leak issues in React development mode, strict mode and server-side rendering, and also ensuring that the SDK is updated if `config` or `factory` props change.
1617
*

0 commit comments

Comments
 (0)