Git Product home page Git Product logo

react-vary's Introduction

react-vary ๐Ÿฑ ๐Ÿ˜ธ ๐Ÿ˜ฝ ๐Ÿ˜ป ๐Ÿ˜น

Statically and Dynamically declare variants for AB testing react components

2 method API

WithVariants()

Similar to the Top-level API of prop-types. Good for scenarios where you'd like to duplicate component logic to avoid pushing variant logic into the component.

import { WithVariants } from 'react-vary';
import MyComp1 from './variants/1';
import MyComp2 from './variants/2';

// The Component that receives the variants will be considered default (variant 0)
class MyComp extends React.Component {
  render() {
    const { props } = this;
    return <div>Variant: {this.props.variant}</div>
  }
}
MyComp.variants = {
  1: MyComp1,
  2: MyComp2
}

const MyCompWithVariants = WithVariants(MyComp);

// However you determine variants is up to you
// Just pass the known variant number down through the parent HOC to render the variant Child
class App extends React.Component {
  render() {
    return (
      <div>
        {/* Variant 0 is our default Component defined above */}
        <MyCompWithVariants variant={0} />
        <MyCompWithVariants variant={1} />
        <MyCompWithVariants variant={2} />

        {/* It also supports render props for dynamic tests */}
        <MyCompWithVariants variant={3} render={({ displayName, variant }) => {
            return <div>DisplayName: {displayName} Variant: {variant}</div>;
        }} />
      </div>
    );
  }
}

By passing a component to WithVariants you get an HOC wrapper back that passes data about your variants via props. Each variant receives the following props.

/**
 * @param {...Object} state - Any changes to state will be passed through
 * @param {...Object} props - The original user-defined Props will be passed through
 * @param {Number} props.variant - The assigned variant number
 * @param {Object} props.variants - Reference to all known variants
 * @param {Boolean} props.isDefault - True if the variant is variant 0
 * @param {Boolean} props.isRenderProp - True if the variant is a render prop
 * @param {Boolean} props.isStaticVariant - True if the variant is a static variant
 * @param {Number} props.staticVariantCount - Total Count of all running static variants
 * @param {Number} props.variantRenderCount - Total number of times the variant has rendered
 */

WithRenderProps()

This method also returns an HOC wrapper but is for scenarios where you'd like the default component to call it's render() function, but all other variants are components with render props that will override the default render() call. Useful for when you want to keep component state in the default variant while only changing the render abilities of your variants.

import { WithRenderProps } from 'react-vary';

class MyStatefulComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      date: new Date()
    }

    this.interval = this.startTimer();
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  startTimer() {
    // update state.date every second and re-render
    return setInterval(() => {
      this.setState({
        date: new Date();
      });
    }, 1000);
  }

  render() {
    const { date } = this.state;
    return <div>Original Render Date: {date}</div>
  }
}

const MyStatefulComponentWithRenderProps = WithRenderProps(MyStatefulComponent);

class App extends React.Component {
  render() {
    return (
      <div>
        {/* Variant 0 is our default Component defined above */}
        <MyStatefulComponentWithRenderProps variant={0} />

        {/*
          Here we get all the state updates but with a custom render override.
          All without touching our original component!
        */}
        <MyStatefulComponentWithRenderProps
          variant={1}
          render={({ props, state }) => <div>Date Override: {state.date}</div>}
        />
      </div>
    );
  }
}

By passing a component to WithRenderProps you get an HOC wrapper back that passes data about your variants via props while automatically invoking state changes as if it were the default component. Each variant receives the following props.

/**
 * @param {...Object} state - Current state that will change based on the behaviour of the default variant
 * @param {...Object} props - The original user-defined Props will be passed through
 * @param {Number} props.variant - The assigned variant number
 * @param {Number} props.variantCount - Total Count of all running  variants
 * @param {Boolean} props.isDefault - True if the variant is variant 0
 * @param {Boolean} props.isRenderProp - True if the variant is a render prop
 * @param {Number} props.totalRenderCount - Total number of times all variants have rendered
 */

More Examples

react-vary's People

Contributors

cmswalker avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.