1.2.0 • Published 6 years ago

ld-redux-components v1.2.0

Weekly downloads
1
License
MIT
Repository
github
Last release
6 years ago

ld-redux-components

npm version npm version npm version npm version build

Feature Flag Components for Launch Darkly that work seemlessly with redux

ld-redux-components is a helper library for Launch Darkly in React that relies on your feature flags being stored in redux.

It is recommended that you use ld-redux, as it provides an easy and clean way to connect Launch Darkly flags to redux, and works as a nice wrapper for ldclient-js.

Getting Started

You should define your Launch Darkly redux strategy before using ld-redux-components. It won't work without your flags in redux. As stated above, ld-redux is the best option, but the only compatability requirement is that you nest your flags in an object of key/value pairs under a key in the base of your redux store. Here is an example of what your store might look like,

{
    ...,
    "LD": {
        "debugger": true,
        "newFeature": "on",
        "tasks": false,
    },
    ...,
}

(note: the above example is using camelCase as ld-redux does, but you can store the flags as lisp-case if you so choose)

Installation

yarn add ld-redux-components
# or
npm install ld-redux-components

Quickstart

  1. In your client bootstrap, initialize ld-redux-components:
import { ldrComponentConfig } from 'ld-redux-components';

//This value will be the key in your redux store where your flags are stored
ldrComponentConfig.init({
  reduxKey: "LD"
});
  1. Import and use Feature and Variant helper components in a component:
import React, { Component } from 'react';
import { Feature, Variant } from 'ld-redux-components';
import { Item } from '<my-app>/item';

export default class FeatureDisplay extends Component {
  render() {
    return (
      <Feature flagId="testFlagId">
        <Variant variation={ true }>
          <Item name="FLAG IS TRUE" icon="smile" color="green" />
        </Variant>
        <Variant variation={ false }>
          <Item name="FLAG IS FALSE" icon="frown" color="red" />
        </Variant>
        <Variant isDefault>
          <Item name="FLAG IS NULL/UNDEFINED" icon="meh" color="blue" />
        </Variant>
      </Feature>
    );
  }
}

Boom! ld-redux-components is working! Notice how there is no need to connect your component, as the Feature component does that heavy lifting for you. Just add Feature and Variant components where you please.

Components

Feature

props

nametyperequireddefaultdescription
flagNamestringtrue-name of flag stored in redux
variationstring, bool, array, nullfalse-value of flag
onReadyfunctionfalse-callback fired when ld connected
waitForLDboolfalsefalsewait to render until ld connected
liveUpdateboolfalsetruererender after initial LD load

Usage Details

  • Feature is primarily used as a wrapper of Variant components.
  • For cases where you only need to either show or not show something, you can set the variation prop. This allows you to avoid using unnecessary Variant components when you only have one variation you care about.
  • variation should not be set if you plan on using Variant components underneath Feature.

Examples

Feature

import React, { Component } from 'react';
import { Feature, Variant } from 'ld-redux-components';
import { Item } from '<my-app>/item';

export default class Display extends Component {
  render() {
    return (
      <Feature flagId="testFlagId">
        <Variant variation={ true }>
          <Item name="FLAG IS TRUE" icon="smile" color="green" />
        </Variant>
        <Variant variation={ false }>
          <Item name="FLAG IS FALSE" icon="frown" color="red" />
        </Variant>
      </Feature>
    );
  }
}

Feature with variation prop set and no Variant components

import React, { Component } from 'react';
import { Feature } from 'ld-redux-components';
import { Item } from '<my-app>/item';

export default class Display extends Component {
  render() {
    return (
      <Feature flagId="testFlagId" variation={ true }>
        <Item name="FLAG IS TRUE" icon="smile" color="green" />
      </Feature>
    );
  }
}

Variant

Variant MUST be defined underneath a Feature component

props

nametyperequireddefaultdescription
variationstring, bool, array, nullfalse-value of flag
isDefaultboolfalsefalsedisplay on null/undefined variation

Usage Details

  • Must be defined underneath Feature component
  • Will always evaluate against the closest parent Feature component (yes, this means you can nest Feature/Variants in other Feature/Variants, and Variants can be deeply nested under Features)
  • isDefault can be used as handler in case a flag is undefined or set to null. You can use this in combination with variation, or by itself

Examples

Two Variants

import React, { Component, Fragment } from 'react';
import { Feature, Variant } from 'ld-redux-components';
import { Item } from '<my-app>/item';

export default class Display extends Component {
  render() {
    return (
      <Feature flagId="testFlagId">
        <Variant variation={ true }>
          <Item name="FLAG IS TRUE" icon="smile" color="green" />
        </Variant>
        <Variant variation={ false }>
          <Item name="FLAG IS FALSE" icon="frown" color="red" />
        </Variant>
      </Feature>
    );
  }
}

Multiple Variants

import React, { Component, Fragment } from 'react';
import { Feature, Variant } from 'ld-redux-components';
import { Item } from '<my-app>/item';

export default class Display extends Component {
  render() {
    return (
      <Feature flagId="testFlagId">
        <Variant variation="control">
          <Item name="FLAG IS TRUE" icon="smile" color="green" />
        </Variant>
        <Variant variation={ ["treatment", "none"] }>
          <Item name="FLAG IS FALSE" icon="frown" color="red" />
        </Variant>
      </Feature>
    );
  }
}

Variant with isDefault

import React, { Component, Fragment } from 'react';
import { Feature, Variant } from 'ld-redux-components';
import { Item } from '<my-app>/item';

export default class Display extends Component {
  render() {
    return (
      <Feature flagId="testFlagId">
        <Variant variation={ true }>
          <Item name="FLAG IS TRUE" icon="smile" color="green" />
        </Variant>
        <Variant isDefault>
          <Item name="FLAG IS NULL/UNDEFINED" icon="meh" color="yellow" />
        </Variant>
      </Feature>
    );
  }
}

Deeply Nested Variant

import React, { Component, Fragment } from 'react';
import { Feature, Variant } from 'ld-redux-components';
import { Item } from '<my-app>/item';
import { SomeOtherComponent } from '<my-app>/someOtherComponent';

export default class Display extends Component {
  render() {
    return (
      <Feature flagId="testFlagId">
        <SomeOtherComponent>
          <Variant variation={ true }>
            <Item name="FLAG IS TRUE" icon="smile" color="green" />
          </Variant>
        </SomeOtherComponent>
        <Variant variation={ false }>
          <Item name="FLAG IS FALSE" icon="frown" color="red" />
        </Variant>
      </Feature>
    );
  }
}

Feature/Variants Nested under Feature/Variants

import React, { Component, Fragment } from 'react';
import { Feature, Variant } from 'ld-redux-components';
import { Item } from '<my-app>/item';

export default class Display extends Component {
  render() {
    return (
      <Feature flagId="testFlagId">
        <Variant variation={ true }>
          <Feature flagId="anotherFlagId">
            <Variant variation="on">
              <Item name="FLAG IS ON" icon="smile" color="green" />
            </Variant>
            <Variant variation="off">
              <Item name="FLAG IS OFF" icon="frown" color="red" />
            </Variant>
          </Feature>
        </Variant>
        <Variant variation={ false }>
          <Item name="FLAG IS FALSE" icon="frown" color="red" />
        </Variant>
      </Feature>
    );
  }
}

Misc.

For a working example, check this example app out (you'll need to provide your own credentials and flags to get things working locally)

Contributions

Welcome!

1.2.0

6 years ago

1.1.0

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago

0.0.1

6 years ago