-
-
Save perenstrom/52b1933f0099868de7ceb0f43c0d3ae1 to your computer and use it in GitHub Desktop.
Medium: AB-test 4
This file contains 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 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