-
Notifications
You must be signed in to change notification settings - Fork 23
/
Experiment.js
93 lines (79 loc) · 2.06 KB
/
Experiment.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
var React = require('react-native');
var {
AsyncStorage,
PropTypes,
View
} = React;
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/>
}
},
componentWillMount() {
this.variants = this.props.children;
this.key = 'react-native-ab:Experiment:' + this.props.name;
AsyncStorage.getItem(this.key, ((err, variantName) => {
var choice;
if (err || !variantName) {
choice = this.props.choose(this.variants);
AsyncStorage.setItem(this.key, choice.props.name); // Optimistic update
}
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;
},
getActiveVariant() {
return this.state.variant;
},
getName() {
return this.props.name;
},
getVariant(name) {
return this.variants.find((v) => v.props.name == name);
},
reset(cb) {
AsyncStorage.removeItem(this.key, cb);
},
_onChange(changed) {
var newState = Object.assign({}, this.state, changed);
this.setState(newState);
}
});
module.exports = Experiment;