Skip to content

Commit 1aa0ec8

Browse files
authored
Merge pull request #784 from dahlbyk/gh781
Improve Prop Change/State Update
2 parents a3ace30 + 4460896 commit 1aa0ec8

File tree

7 files changed

+137
-8
lines changed

7 files changed

+137
-8
lines changed

src/actions/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ export function setPageSize(pageSize) {
6363
}
6464
}
6565

66-
export function updateState({ data, pageProperties = {}, sortProperties = {} }) {
66+
export function updateState(newState) {
6767
return {
6868
type: GRIDDLE_UPDATE_STATE,
69-
newState: { data, pageProperties, sortProperties }
69+
newState
7070
}
7171
}

src/module.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ export interface GriddleSortKey {
315315
export interface GriddleStyleElements<T> {
316316
Cell?: T;
317317
Filter?: T;
318+
Layout?: T;
318319
Loading?: T;
319320
NextButton?: T;
320321
NoResults?: T;

src/reducers/__tests__/dataReducerTest.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,71 @@ test('toggle column works when there is no visible property', (t) => {
183183

184184

185185
});
186+
187+
test('update state merges non-data', (t) => {
188+
const initialState = Immutable.fromJS({
189+
changed: 1,
190+
unchanged: 2,
191+
nested: {
192+
changed: 3,
193+
unchanged: 4,
194+
},
195+
data: [],
196+
lookup: {},
197+
});
198+
const newState = {
199+
changed: -1,
200+
nested: {
201+
changed: -3,
202+
},
203+
};
204+
205+
const state = reducers.GRIDDLE_UPDATE_STATE(initialState, { newState });
206+
207+
t.deepEqual(state.toJSON(), {
208+
changed: -1,
209+
unchanged: 2,
210+
nested: {
211+
changed: -3,
212+
unchanged: 4,
213+
},
214+
data: [],
215+
lookup: {},
216+
});
217+
});
218+
219+
test('update state transforms data', (t) => {
220+
const initialState = Immutable.fromJS({
221+
unchanged: 2,
222+
nested: {
223+
unchanged: 4,
224+
},
225+
data: [
226+
{name: "one", griddleKey: 0},
227+
{name: "two", griddleKey: 1},
228+
],
229+
lookup: { 0: 0, 1: 1 },
230+
});
231+
const newState = {
232+
data: [
233+
{ name: 'uno' },
234+
{ name: 'dos' },
235+
{ name: 'tre' },
236+
]
237+
};
238+
239+
const state = reducers.GRIDDLE_UPDATE_STATE(initialState, { newState });
240+
241+
t.deepEqual(state.toJSON(), {
242+
unchanged: 2,
243+
nested: {
244+
unchanged: 4,
245+
},
246+
data: [
247+
{name: "uno", griddleKey: 0},
248+
{name: "dos", griddleKey: 1},
249+
{name: "tre", griddleKey: 2},
250+
],
251+
lookup: { 0: 0, 1: 1, 2: 2 },
252+
});
253+
});

src/reducers/dataReducer.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,19 @@ export function GRIDDLE_TOGGLE_COLUMN(state, action) {
132132
new Immutable.Map({ id: action.columnId, visible: true }));
133133
}
134134

135+
const defaultRenderProperties = Immutable.fromJS({});
135136
export function GRIDDLE_UPDATE_STATE(state, action) {
136137
const { data, ...newState } = action.newState;
137-
const transformedData = transformData(data, state.get('renderProperties').toJSON());
138138

139-
return state.mergeDeep(Immutable.fromJS(newState))
139+
var mergedState = state.mergeDeep(Immutable.fromJS(newState));
140+
if (!data) {
141+
return mergedState;
142+
}
143+
144+
const renderProperties = state.get('renderProperties', defaultRenderProperties).toJSON();
145+
const transformedData = transformData(data, renderProperties);
146+
147+
return mergedState
140148
.set('data', transformedData.data)
141149
.set('lookup', transformedData.lookup);
142150
}

src/utils/__tests__/initilizerTests.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ test('init succeeds given empty defaults and props', (assert) => {
6060
test('init returns defaults given minimum props', (assert) => {
6161
const ctx = { props: { data: [] } };
6262
const defaults = {
63-
reducers: { REDUCE: () => ({ reduced: true }) },
63+
reducer: { REDUCE: () => ({ reduced: true }) },
6464
components: { Layout: () => null },
6565
settingsComponentObjects: { mySettings: { order: 10 } },
6666
selectors: { aSelector: () => null },
@@ -82,7 +82,7 @@ test('init returns defaults given minimum props', (assert) => {
8282
});
8383

8484
assert.is(typeof res.reducers, 'function');
85-
assert.deepEqual(Object.keys(res.reducers), Object.keys(defaults.reducers));
85+
assert.deepEqual(Object.keys(res.reducers), Object.keys(defaults.reducer));
8686
assert.deepEqual(res.reducers({}, { type: 'REDUCE' }), { reduced: true });
8787

8888
assert.deepEqual(res.reduxMiddleware, []);
@@ -244,7 +244,7 @@ test('init returns composed reducer given plugins', (assert) => {
244244
},
245245
};
246246
const defaults = {
247-
reducers: {
247+
reducer: {
248248
DEFAULTS: () => ({ defaults: true }),
249249
PLUGIN: () => ({ plugin: false }),
250250
},

src/utils/initializer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module.exports = function initializer(defaults) {
77
if (!this) throw new Error('this missing!');
88

99
const {
10-
reducers: dataReducers,
10+
reducer: dataReducers,
1111
components,
1212
settingsComponentObjects,
1313
selectors,

stories/index.tsx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,58 @@ storiesOf('Griddle main', module)
105105
</Griddle>
106106
)
107107
})
108+
.add('with external prop changes', () => {
109+
const NoResultsWithN = connect(
110+
(state: any) => ({
111+
n: state.get('n'),
112+
addTen: state.get('addTen'),
113+
}),
114+
() => {}
115+
)(({ n, addTen }) => (
116+
<div>
117+
<p><code>n = {n}</code></p>
118+
<button onClick={addTen}>+10</button>
119+
</div>
120+
));
121+
122+
class Stateful extends React.Component<{}, { n: number }> {
123+
constructor(props) {
124+
super(props);
125+
this.state = { n: 0 };
126+
}
127+
128+
render() {
129+
const { n } = this.state;
130+
return (
131+
<div>
132+
<p>
133+
Click to change Griddle props:{' '}
134+
<button onClick={() => this.setState(({ n }) => ({ n: n+1 }))}>{n}</button>
135+
<button onClick={() => this.setState({ n: 0 })}>Reset</button>
136+
</p>
137+
<Griddle
138+
n={n}
139+
addTen={() => this.setState(({ n }) => ({ n: n + 10 }))}
140+
plugins={[LocalPlugin]}
141+
data={fakeData.filter((d,i) => i % n === 0)}
142+
components={{
143+
NoResults: NoResultsWithN
144+
}}
145+
styleConfig={{
146+
styles: {
147+
Layout: { color: n % 3 ? 'blue' : 'inherit' },
148+
},
149+
}}
150+
textProperties={{
151+
settingsToggle: `Settings (${n})`
152+
}}
153+
/>
154+
</div>
155+
);
156+
}
157+
}
158+
return <Stateful />;
159+
})
108160
.add('with local, delayed data', () => {
109161
class DeferredGriddle extends React.Component<GriddleProps<FakeData>, { data?: FakeData[] }> {
110162
private timeout;

0 commit comments

Comments
 (0)