forked from lwansbrough/react-native-ab
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Experiment.js
95 lines (80 loc) · 2.04 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
94
95
import React, {
Component,
PropTypes
} from 'react';
import {
AsyncStorage,
View
} from 'react-native';
class Experiment extends Component {
constructor(props) {
super(props);
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) => {
let 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));
}
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);
}
render() {
return this.state.variant;
}
};
Experiment.propTypes = {
name: PropTypes.string.isRequired,
children: ((props, propName) => {
let 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.name === 'Variant') {
return new Error('One or more children is not a Variant.');
}
}
}),
choose: PropTypes.func,
onChoice: PropTypes.func,
onRawChoice: PropTypes.func
};
Experiment.defaultProps = {
choose(variants) {
let choice = Math.floor(Math.random() * variants.length);
return variants[choice];
},
onChoice(testName, variantName) { /* noop */ },
onRawChoice(test, variant) { /* noop */ }
};
export default Experiment;