From 6783cf6b549304249421f551ddc4782cfb87edd5 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Fri, 9 Aug 2019 12:44:33 -0500 Subject: [PATCH 1/3] Created useSplit hook --- README.md | 25 +++++++++++++++++++++---- src/index.ts | 1 + src/useSplit.ts | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 src/useSplit.ts diff --git a/README.md b/README.md index 1ca0a90..89e33ae 100644 --- a/README.md +++ b/README.md @@ -78,10 +78,27 @@ Split allows you to [implement a custom impression listener](https://help.split. ## Usage -Now assuming you have a split named: `feature1` you can do something like: +Now assuming you have a split named `feature1` you can do something like: -```jsx - +### Hook + +```tsx +const [feature1, config] = useSplit('feature1'); +if (feature1 === 'on') { + return ; +} +``` + +Optional [attributes](https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#attribute-syntax) +can also be passed in: +```tsx +const [feature1, config] = useSplit('feature1', { paying_customer: true }); +``` + +### Component + +```tsx + {(value: TreatmentWithConfig) => value.treatment === 'on' ? this.renderComponent() : null } @@ -90,7 +107,7 @@ Now assuming you have a split named: `feature1` you can do something like: You can optionally pass a list of splits: -```jsx +```tsx {(values: TreatmentsWithConfig) => { console.log(values); diff --git a/src/index.ts b/src/index.ts index af6711e..76a1528 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,3 @@ export { default as Split } from './Split'; export { default as SplitProvider, SplitContext } from './SplitProvider'; +export * from './useSplit'; diff --git a/src/useSplit.ts b/src/useSplit.ts new file mode 100644 index 0000000..6aff259 --- /dev/null +++ b/src/useSplit.ts @@ -0,0 +1,33 @@ +import { + Attributes, + TreatmentWithConfig, +} from '@splitsoftware/splitio/types/splitio'; +import { useContext, useEffect, useState } from 'react'; +import { SplitContext } from './SplitProvider'; + +/** + * Returns a treatment and it's config. + * @param {string} splitName - The string that represents the split we want to get the treatment. + * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. + * @returns {[string, string | null]} Tuple with treatment first and config second. + */ +export const useSplit = ( + splitName: string, + attributes?: Attributes, +): [string, string | null] => { + const { client, isReady, lastUpdate } = useContext(SplitContext); + const [{ treatment, config }, setTreatment] = useState(defaultTreatment); + useEffect(() => { + const next = + client && isReady + ? client.getTreatmentWithConfig(splitName, attributes) + : defaultTreatment; + setTreatment(next); + }, [client, isReady, lastUpdate]); + return [treatment, config]; +}; + +const defaultTreatment: TreatmentWithConfig = { + config: null, + treatment: 'control', // SplitIO's default value +}; From 78046772e5f0cf551aeaa7bfe91224ef46f84517 Mon Sep 17 00:00:00 2001 From: Carson Full Date: Fri, 9 Aug 2019 12:47:09 -0500 Subject: [PATCH 2/3] Created useTrack hook --- README.md | 11 +++++++++++ src/index.ts | 1 + src/useTrack.ts | 10 ++++++++++ 3 files changed, 22 insertions(+) create mode 100644 src/useTrack.ts diff --git a/README.md b/README.md index 89e33ae..114ed32 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,17 @@ You can optionally pass a list of splits: ``` +### Tracking + +We have a `useTrack` hook which returns the a function with the same signature as +[`client.track`](https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#track). +```tsx +const track = useTrack(); +function handleClick() { + const queued = track('user', 'click', 'the_button', { foo: 'bar' }); +} +``` + ## Contributing ### Fork and Clone the Project diff --git a/src/index.ts b/src/index.ts index 76a1528..91a3b48 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ export { default as Split } from './Split'; export { default as SplitProvider, SplitContext } from './SplitProvider'; export * from './useSplit'; +export * from './useTrack'; diff --git a/src/useTrack.ts b/src/useTrack.ts new file mode 100644 index 0000000..9a353a5 --- /dev/null +++ b/src/useTrack.ts @@ -0,0 +1,10 @@ +import { IClient } from '@splitsoftware/splitio/types/splitio'; +import { useContext } from 'react'; +import { SplitContext } from './SplitProvider'; + +export const useTrack: () => IClient['track'] = () => { + const { client, isReady } = useContext(SplitContext); + return client && isReady ? client.track : defaultTrack; +}; + +const defaultTrack = () => false; From 89ca96fa5e2d59e809a0dea99e2e03ee120512af Mon Sep 17 00:00:00 2001 From: Carson Full Date: Thu, 22 Aug 2019 14:59:01 -0500 Subject: [PATCH 3/3] Convert Split to use hooks --- src/Split.tsx | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/Split.tsx b/src/Split.tsx index 00f1764..4167efc 100644 --- a/src/Split.tsx +++ b/src/Split.tsx @@ -1,6 +1,6 @@ -import React from 'react'; +import { useContext } from 'react'; import { SplitContext } from './SplitProvider'; -import { ISplitContextValues, ISplitProps } from './types'; +import { ISplitProps } from './types'; /** * Component that will receive a split prop, connect on SplitContext and return treatment when SDK is ready. @@ -12,20 +12,17 @@ import { ISplitContextValues, ISplitProps } from './types'; * {(value: TreatmentWithConfig) => value.treatment === 'on' ? this.renderComponent() : null} * */ -const Split: React.SFC = ({ name, children }) => ( - - {({ client, isReady, lastUpdate }: ISplitContextValues) => - children( - client && isReady - ? name instanceof Array - ? client.getTreatmentsWithConfig(name as string[]) - : client.getTreatmentWithConfig(name as string) - : null, - client, - lastUpdate, - ) - } - -); +const Split = ({ name, children }: ISplitProps) => { + const { client, isReady, lastUpdate } = useContext(SplitContext); + return children( + client && isReady + ? name instanceof Array + ? client.getTreatmentsWithConfig(name as string[]) + : client.getTreatmentWithConfig(name as string) + : null, + client, + lastUpdate, + ); +}; export default Split;