Last active
May 24, 2018 03:55
-
-
Save johntran/f346ae7d186dcb4706092605dfff13ab to your computer and use it in GitHub Desktop.
Feature Flags: React 16 Context + TypeScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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