Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 56 additions & 77 deletions Experiment.js
Original file line number Diff line number Diff line change
@@ -1,93 +1,72 @@
var React = require('react-native');
var {
import React from 'react'
import PropTypes from 'prop-types'
import {
AsyncStorage,
PropTypes,
View
} = React;
View,
} from 'react-native'

var Experiment = React.createClass({

propTypes: {
name: PropTypes.string.isRequired,
children: ((props, propName) => {
var children = props[propName];
if (!Array.isArray(children) || children.length < 2) {
return new Error('You must have at least 2 Variants.');
}
for (child of children) {
if (!child.type.prototype.isVariant) {
return new Error('One or more children is not a Variant.');
}
}
}),
choose: PropTypes.func,
onChoice: PropTypes.func,
onRawChoice: PropTypes.func
},

getDefaultProps() {
return {
choose(variants) {
var choice = Math.floor(Math.random() * variants.length);
return variants[choice];
},
onChoice(testName, variantName) { /* noop */ },
onRawChoice(test, variant) { /* noop */ }
}
},

getInitialState() {
return {
variant: <View/>
export default class Experiment extends React.Component {
constructor(props) {
super(props)
this.key = `react-native-ab:Experiment:${props.name}`
this.variants = props.children
this.state = {
variant: <View />,
}
},
}

componentWillMount() {
this.variants = this.props.children;

this.key = 'react-native-ab:Experiment:' + this.props.name;

AsyncStorage.getItem(this.key, ((err, variantName) => {
var choice;
let variant
if (err || !variantName) {
choice = this.props.choose(this.variants);
AsyncStorage.setItem(this.key, choice.props.name); // Optimistic update
variant = this.props.choose(this.variants)
AsyncStorage.setItem(this.key, variant.props.name)
} else {
variant = this.getVariant(variantName)
}
else {
choice = this.getVariant(variantName);
}
this.props.onChoice(this.props.name, choice.props.name);
this.props.onRawChoice(this, choice);
this._onChange({
variant: choice
});
}).bind(this));
},

render() {
return this.state.variant;
},
this.props.onChoice(this.props.name, variant.props.name)
this.props.onRawChoice(this, variant)
this.setState({ variant })
}))
}

getActiveVariant() {
return this.state.variant;
},
getActiveVariant = () => this.state.variant

getName() {
return this.props.name;
},
getName = () => this.props.name

getVariant(name) {
return this.variants.find((v) => v.props.name == name);
},
getVariant = name => this.variants.find(v => v.props.name === name)

reset(cb) {
AsyncStorage.removeItem(this.key, cb);
},
reset = (cb) => {
AsyncStorage.removeItem(this.key, cb)
}

_onChange(changed) {
var newState = Object.assign({}, this.state, changed);
this.setState(newState);
render() {
return this.state.variant
}
});
}

Experiment.defaultProps = {
choose(variants) {
const choice = Math.floor(Math.random() * variants.length)
return variants[choice]
},
onChoice(testName, variantName) { /* noop */ },
onRawChoice(test, variant) { /* noop */ },
}

module.exports = Experiment;
Experiment.propTypes = {
name: PropTypes.string.isRequired,
children: ((props, propName) => {
const children = props[propName]
if (!Array.isArray(children) || children.length < 2) {
return new Error('You must have at least 2 Variants.')
}
if (children.some(child => !child.type.isVariant)) {
return new Error('One or more children is not a Variant.')
}
}),
choose: PropTypes.func,
onChoice: PropTypes.func,
onRawChoice: PropTypes.func,
}
15 changes: 0 additions & 15 deletions Tracking.js

This file was deleted.

29 changes: 13 additions & 16 deletions Variant.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
var React = require('react-native');
var { PropTypes } = React;
import React from 'react'
import PropTypes from 'prop-types'

var Variant = React.createClass({
propTypes: {
name: PropTypes.string.isRequired,
children: PropTypes.element.isRequired
},

render() {
return this.props.children;
},
export default class Variant extends React.Component {
static isVariant = true

getName() {
return this.props.name;
},
getName = () => this.props.name

isVariant: true
});
render() {
return this.props.children
}
}

module.exports = Variant;
Variant.propTypes = {
name: PropTypes.string.isRequired,
children: PropTypes.element.isRequired,
}
12 changes: 7 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module.exports = {
Experiment: require('./Experiment'),
Tracking: require('./Tracking'),
Variant: require('./Variant')
};
import Variant from './Variant'
import Experiment from './Experiment'

export {
Experiment,
Variant,
}