Skip to content

Instantly share code, notes, and snippets.

@johntran
Last active May 24, 2018 03:55
Show Gist options
  • Save johntran/f346ae7d186dcb4706092605dfff13ab to your computer and use it in GitHub Desktop.
Save johntran/f346ae7d186dcb4706092605dfff13ab to your computer and use it in GitHub Desktop.
Feature Flags: React 16 Context + TypeScript
import * as React from 'react';
import {withFeatureFlags} from './FeatureFlag'
@withFeatureFlags(['TEMP_20180523_123_DELETE_PAYMENTS'])
class EditPaymentDialog extends React.Component<{}, {}> {
render() {
const { featureFlags } = this.props;
const { TEMP_20180523_123_DELETE_PAYMENTS } = featureFlags;
if (TEMP_20180523_123_DELETE_PAYMENTS) return <div />;
return null;
}
}
import * as React from 'react';
interface FEATURE_FLAGS {
// true or false toggles this on and off.
TEMP_2018_05_23_123_DELETE_PAYMENTS: boolean | undefined;
// can be 1 or 2. 1 returns one page. 2 returns another page
AB_2018_05_23_234_CEO_LANDING_PAGE: number | undefined;
IN_PROGRESS_2018_05_23_345_MARKETPLACE_RESULTS: boolean | undefined;
}
function getValue(value: string | undefined, type: string | undefined) {
if (value === undefined || type === undefined) return undefined;
switch (type) {
case 'boolean':
return value === 'true';
case 'float':
return parseFloat(value);
case 'string':
return value;
default:
return undefined;
}
}
export function normalizeFeatureFlag(
featureFlagQueryResults: [string, string, string][],
/**
* ex: [
* ['TEMP_2018_05_23_123_DELETE_PAYMENTS', 'true', 'boolean'],
* ['AB_2018_05_23_234_CEO_LANDING_PAGE', '1', 'float'],
* ['IN_PROGRESS_2018_05_23_345_MARKETPLACE_RESULTS', 'false', 'boolean'],
* ]
*/
) {
return featureFlagQueryResults.reduce(
(acc, [name, value, type]) => ({ ...acc, [name]: getValue(value, type) }),
{},
);
/**
* returns
const featureFlags = {
'TEMP_2018_05_23_123_DELETE_PAYMENTS': true,
'AB_2018_05_23_234_CEO_LANDING_PAGE': 1,
'IN_PROGRESS_2018_05_23_345_MARKETPLACE_RESULTS': false,
};
*/
}
export const FeatureFlagContext = React.createContext({});
export function withFeatureFlags<T>(flags: string[]) {
return (Component: React.ReactNode) => (props: any) => (
<FeatureFlagContext.Consumer>
{({ featureFlags }: { featureFlags: T }) => (
<Component
featureFlags={flags.reduce(
(acc, curr) => ({ ...acc, [curr]: featureFlags[curr] }),
{},
)}
{...props}
/>
)}
</FeatureFlagContext.Consumer>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment