-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathwithState.js
103 lines (86 loc) · 2.26 KB
/
withState.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
96
97
98
99
100
101
102
103
// @flow
import React from 'react';
import update from 'immutability-helper';
import get from 'lodash/get';
import isEqual from 'lodash/isEqual';
import noop from 'lodash/noop';
type Props = {
formData: Object;
formMeta: Object;
onChange: Function;
};
type State = {
formData: Object;
formMeta: Object;
}
const withState = (defaultConfig: Object = {}) => (Component: ReactClass<any>): ReactClass<any> => {
const config = {
formData: {},
formMeta: {},
shouldComponentUpdate: null,
...defaultConfig
}
class ComponentWithState extends React.Component {
props: Props
static defaultProps: Props = {
formData: {},
formMeta: {},
onChange: noop
}
state: State = {
formData: {},
formMeta: {}
}
componentWillMount = (): void => {
this.setState({
formData: {
...config.formData,
...this.props.formData
},
formMeta: {
...config.formMeta,
...this.props.formMeta
}
});
}
shouldComponentUpdate = (nextProps: Props, nextState: State): boolean => {
if (config.shouldComponentUpdate) {
return config.shouldComponentUpdate(nextProps, nextState);
}
return !isEqual(this.props, nextProps)
|| !isEqual(this.state, nextState);
}
componentWillReceiveProps = (nextProps: Props): void => {
this.setState({
formData: this.refreshData('formData', nextProps),
formMeta: this.refreshData('formMeta', nextProps)
});
}
refreshData = (key: string, nextProps: Props): Object => (
update(nextProps[key], {
$merge: get(this.state, [key], {})
})
)
handleChange = (syntheticFormEvent: SyntheticFormEvent): void => {
syntheticFormEvent.removeEventActions();
this.setState({
formData: {...syntheticFormEvent.formData},
formMeta: {...syntheticFormEvent.formMeta}
}, () => {
this.props.onChange(syntheticFormEvent);
});
}
render() {
return (
<Component
{...this.props}
formData={this.state.formData}
formMeta={this.state.formMeta}
onChange={this.handleChange}
/>
);
}
}
return ComponentWithState;
};
export default withState;