Skip to content
This repository was archived by the owner on Aug 23, 2022. It is now read-only.

Commit a1204a1

Browse files
committed
Merge pull request #8 from jihchi/add_supports_for_structural_sharing
Use "icepick" to set/merge data strcuture instead of lodash's set/merge with cloneDeep
2 parents 388f325 + 36232a9 commit a1204a1

File tree

3 files changed

+46
-54
lines changed

3 files changed

+46
-54
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"webpack": "^1.12.9"
5454
},
5555
"dependencies": {
56+
"icepick": "^1.1.0",
5657
"lodash": "^4.0.0",
5758
"react": "^0.14.6",
5859
"react-dom": "^0.14.3",

src/reducers/form-reducer.js

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
1+
import every from 'lodash/every';
12
import get from 'lodash/get';
2-
import set from 'lodash/set';
3-
import merge from 'lodash/merge';
4-
import toPath from 'lodash/toPath';
5-
import isPlainObject from 'lodash/isPlainObject';
3+
import icepick from 'icepick';
64
import isBoolean from 'lodash/isBoolean';
7-
import mapValues from 'lodash/mapValues';
8-
import every from 'lodash/every';
9-
import cloneDeep from 'lodash/cloneDeep';
105
import isEqual from 'lodash/isEqual';
6+
import isPlainObject from 'lodash/isPlainObject';
7+
import mapValues from 'lodash/mapValues';
8+
import toPath from 'lodash/toPath';
119

1210
import * as actionTypes from '../action-types';
1311

1412
function setField(state, localPath, props) {
1513
if (!localPath.length) {
16-
return merge(cloneDeep(state), props);
17-
};
14+
return icepick.merge(state, props);
15+
}
1816

19-
return merge(cloneDeep(state), {
17+
return icepick.merge(state, {
2018
fields: {
2119
[localPath.join('.')]: {
2220
...initialFieldState,
@@ -28,7 +26,7 @@ function setField(state, localPath, props) {
2826
}
2927

3028
function getField(state, path) {
31-
let localPath = toPath(path);
29+
const localPath = toPath(path);
3230

3331
return get(
3432
state,
@@ -59,7 +57,7 @@ const initialFormState = {
5957
function createInitialFormState(model) {
6058
return {
6159
...initialFormState,
62-
model: model
60+
model
6361
};
6462
}
6563

@@ -68,116 +66,112 @@ function createFormReducer(model) {
6866

6967
return (state = createInitialFormState(model), action) => {
7068
if (!action.model) return state;
71-
72-
let path = toPath(action.model);
69+
70+
const path = toPath(action.model);
7371

7472
if (!isEqual(path.slice(0, modelPath.length), modelPath)) {
7573
return state;
7674
}
7775

78-
let localPath = path.slice(modelPath.length);
79-
80-
let form = cloneDeep(state);
76+
const localPath = path.slice(modelPath.length);
8177

8278
switch (action.type) {
8379
case actionTypes.FOCUS:
84-
return setField(form, localPath, {
80+
return setField(state, localPath, {
8581
focus: true,
8682
blur: false
8783
});
8884

8985
case actionTypes.CHANGE:
9086
case actionTypes.SET_DIRTY:
91-
merge(form, {
87+
state = icepick.merge(state, {
9288
dirty: true,
9389
pristine: false,
9490
});
9591

96-
return setField(form, localPath, {
92+
return setField(state, localPath, {
9793
dirty: true,
9894
pristine: false
9995
});
10096

10197
case actionTypes.BLUR:
10298
case actionTypes.SET_TOUCHED:
103-
return setField(form, localPath, {
99+
return setField(state, localPath, {
104100
touched: true,
105101
untouched: false,
106102
focus: false,
107103
blur: true
108104
});
109105

110106
case actionTypes.SET_PENDING:
111-
return setField(form, localPath, {
107+
return setField(state, localPath, {
112108
pending: action.pending,
113109
submitted: false
114110
});
115111

116112
case actionTypes.SET_VALIDITY:
117-
let errors = isPlainObject(action.validity)
113+
const errors = isPlainObject(action.validity)
118114
? {
119-
...getField(form, localPath).errors,
115+
...getField(state, localPath).errors,
120116
...mapValues(action.validity, (valid) => !valid)
121117
}
122118
: !action.validity;
123119

124-
form = setField(form, localPath, {
125-
errors: errors,
120+
state = setField(state, localPath, {
121+
errors,
126122
valid: isBoolean(errors)
127123
? errors
128124
: every(errors, (error) => !error)
129125
});
130126

131-
return merge(form, {
132-
valid: every(mapValues(form.fields, (field) => field.valid))
133-
&& every(form.errors, (error) => !error)
127+
return icepick.merge(state, {
128+
valid: every(mapValues(state.fields, (field) => field.valid))
129+
&& every(state.errors, (error) => !error)
134130
});
135131

136-
break;
137-
138132
case actionTypes.SET_PRISTINE:
139-
form = setField(form, localPath, {
133+
state = setField(state, localPath, {
140134
dirty: false,
141135
pristine: true
142136
});
143137

144-
let formIsPristine = every(mapValues(form.fields, (field) => field.pristine));
138+
const formIsPristine = every(mapValues(state.fields, (field) => field.pristine));
145139

146-
return merge(form, {
140+
return icepick.merge(state, {
147141
pristine: formIsPristine,
148142
dirty: !formIsPristine
149143
});
150144

151145
case actionTypes.SET_UNTOUCHED:
152-
return setField(form, localPath, {
146+
return setField(state, localPath, {
153147
touched: false,
154148
untouched: true
155149
});
156150

157151
case actionTypes.SET_SUBMITTED:
158-
return setField(form, localPath, {
152+
return setField(state, localPath, {
159153
pending: false,
160154
submitted: !!action.submitted
161155
});
162156

163157
case actionTypes.SET_INITIAL:
164158
case actionTypes.RESET:
165-
return setField(form, localPath, initialFieldState);
159+
return setField(state, localPath, initialFieldState);
166160

167161
case actionTypes.SET_VIEW_VALUE:
168-
return setField(form, localPath, {
162+
return setField(state, localPath, {
169163
viewValue: action.value
170164
});
171165

172166
default:
173-
return form;
167+
return state;
174168
}
175-
}
169+
};
176170
}
177171

178172
export {
179173
createFormReducer,
180174
initialFieldState,
181175
initialFormState,
182176
getField
183-
}
177+
};

src/reducers/model-reducer.js

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import get from 'lodash/get';
2-
import set from 'lodash/set';
3-
import startsWith from 'lodash/startsWith';
4-
import cloneDeep from 'lodash/cloneDeep';
5-
import toPath from 'lodash/toPath';
2+
import icepick from 'icepick';
63
import isEqual from 'lodash/isEqual';
4+
import toPath from 'lodash/toPath';
75

86
import * as actionTypes from '../action-types';
97

@@ -13,39 +11,38 @@ function createModelReducer(model, initialState = {}) {
1311
return (state = initialState, action) => {
1412
if (!action.model) return state;
1513

16-
let path = toPath(action.model);
14+
const path = toPath(action.model);
1715

1816
if (!isEqual(path.slice(0, modelPath.length), modelPath)) {
1917
return state;
2018
}
2119

22-
let localPath = path.slice(modelPath.length);
23-
let newState = cloneDeep(state);
20+
const localPath = path.slice(modelPath.length);
2421

2522
switch (action.type) {
2623
case actionTypes.CHANGE:
2724
if (!localPath.length) {
2825
return action.value;
2926
}
3027

31-
return set(newState, localPath, action.value);
28+
return icepick.setIn(state, localPath, action.value);
3229

3330
case actionTypes.RESET:
3431
if (!localPath.length) {
3532
return initialState;
3633
}
3734

38-
return set(
39-
newState,
35+
return icepick.setIn(
36+
state,
4037
localPath,
4138
get(initialState, localPath));
4239

4340
default:
44-
return newState;
41+
return state;
4542
}
46-
}
43+
};
4744
}
4845

4946
export {
5047
createModelReducer
51-
}
48+
};

0 commit comments

Comments
 (0)