Skip to content

Instantly share code, notes, and snippets.

@perenstrom
Created June 21, 2019 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save perenstrom/52b1933f0099868de7ceb0f43c0d3ae1 to your computer and use it in GitHub Desktop.
Save perenstrom/52b1933f0099868de7ceb0f43c0d3ae1 to your computer and use it in GitHub Desktop.
Medium: AB-test 4
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
// Helpers
import * as cookie from '~/App/helpers/cookie';
// Redux
import { getAbCohortId } from '~/App/shared/reducers';
import { abActions } from '~/App/shared/actions';
// Shared components
import { Variant } from './';
class ExperimentComponent extends React.Component {
constructor(props) {
super(props);
// Set cohort on server and client
let cohortId = 0;
let cohortSet = false;
if (
props.cohortId !== undefined &&
props.cohortId !== null &&
typeof props.cohortId === 'number' &&
Number.isFinite(props.cohortId) &&
props.cohortId >= 0 &&
props.cohortId < 1
) {
cohortId = props.cohortId;
cohortSet = true;
}
this.state = {
cohortId,
cohortSet
};
}
componentDidMount() {
const variantChildren = React.Children.toArray(this.props.children);
const numberOfVariants = variantChildren.length;
const { experimentId } = this.props;
// Set cohort on client
if (!this.state.cohortSet) {
const cohortIdFromCookie = cookie.get('cohortId');
const cohortId = cohortIdFromCookie === null ? 0 : cohortIdFromCookie;
this.setState({ cohortId: cohortId, cohortSet: true });
this.props.abActions.updateCohortId({ cohortId });
this.setExperimentCookie(
experimentId,
this.getVariantId(cohortId, numberOfVariants)
);
} else {
this.setExperimentCookie(
experimentId,
this.getVariantId(this.props.cohortId, numberOfVariants)
);
}
}
getVariantId(cohortId, numberOfVariants) {
return Math.floor(cohortId * numberOfVariants);
}
setExperimentCookie(experimentId, variantId) {
if (!cookie.get('cf_experiment')) {
cookie.set('cf_experiment', `${experimentId}.${variantId}`, 1);
}
}
renderActiveVariant() {
const variantChildren = React.Children.toArray(this.props.children);
try {
variantChildren.forEach((child) => {
if (!(child.type === Variant)) {
throw new Error('Child has to be of class Variant');
}
});
} catch (error) {
return null;
}
const numberOfVariants = variantChildren.length;
const variantToChoose = this.getVariantId(
this.state.cohortId,
numberOfVariants
);
return variantChildren[variantToChoose];
}
render() {
return this.renderActiveVariant();
}
}
const mapStateToProps = (state) => ({
cohortId: getAbCohortId(state)
});
const mapDispatchToProps = (dispatch) => ({
abActions: bindActionCreators(abActions, dispatch)
});
export const Experiment = connect(
mapStateToProps,
mapDispatchToProps
)(ExperimentComponent);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment