Skip to content

Commit 232c3c0

Browse files
committed
Refactor wrapper selectors to use path sums as equality comparator
1 parent e023e4f commit 232c3c0

File tree

3 files changed

+39
-18
lines changed

3 files changed

+39
-18
lines changed

dash/dash-renderer/src/reducers/layout.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {includes, mergeRight, path} from 'ramda';
1+
import {includes, mergeRight, append, view, lensPath, assocPath} from 'ramda';
22

33
import {getAction} from '../actions/constants';
44

@@ -15,8 +15,10 @@ const layout = (state = {}, action) => {
1515
getAction('ON_PROP_CHANGE')
1616
])
1717
) {
18-
const component = path(action.payload.itempath, state);
19-
component.props = mergeRight(component.props, action.payload.props);
18+
const propPath = append('props', action.payload.itempath);
19+
const existingProps = view(lensPath(propPath), state);
20+
const mergedProps = mergeRight(existingProps, action.payload.props);
21+
return assocPath(propPath, mergedProps, state);
2022
}
2123

2224
return state;

dash/dash-renderer/src/reducers/reducer.js

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {forEach, isEmpty, keys, path} from 'ramda';
1+
import {forEach, includes, isEmpty, keys, path, assoc, pathOr} from 'ramda';
22
import {combineReducers} from 'redux';
33

44
import {getCallbacksByInput} from '../actions/dependencies_ts';
@@ -26,14 +26,19 @@ export const apiRequests = [
2626
'loginRequest'
2727
];
2828

29-
function callbackNum(state = 0, action) {
30-
// With the refactor of TreeContainer to DashWrapper
31-
// The props are updated partially and no longer
32-
// trigger the selectors on change.
33-
// By changing this store value we circumvent
34-
// the issue.
35-
if (action.type === 'ON_PROP_CHANGE') {
36-
return state + 1;
29+
function layoutHashes(state = {}, action) {
30+
if (
31+
includes(action.type, [
32+
'UNDO_PROP_CHANGE',
33+
'REDO_PROP_CHANGE',
34+
'ON_PROP_CHANGE'
35+
])
36+
) {
37+
// Let us compare the paths sums to get updates without triggering
38+
// render on the parent containers.
39+
const jsonPath = JSON.stringify(action.payload.itempath);
40+
const prev = pathOr(0, [jsonPath], state);
41+
return assoc(jsonPath, prev + 1, state);
3742
}
3843
return state;
3944
}
@@ -52,7 +57,7 @@ function mainReducer() {
5257
isLoading,
5358
layout,
5459
paths,
55-
callbackNum,
60+
layoutHashes,
5661
loading
5762
};
5863
forEach(r => {

dash/dash-renderer/src/wrapper/selectors.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,34 @@ import {path} from 'ramda';
22

33
import {DashLayoutPath, DashComponent, BaseDashProps} from '../types/component';
44

5-
type SelectDashProps = [DashComponent, BaseDashProps];
5+
type SelectDashProps = [DashComponent, BaseDashProps, number];
66

77
export const selectDashProps =
88
(componentPath: DashLayoutPath) =>
99
(state: any): SelectDashProps => {
1010
const c = path(componentPath, state.layout) as DashComponent;
11-
return [c, c.props];
11+
// Layout hashes records the number of times a path has been updated.
12+
// sum with the parents hash (match without the last ']') to get the real hash
13+
// Then it can be easily compared without having to compare the props.
14+
let jsonPath = JSON.stringify(componentPath);
15+
jsonPath = jsonPath.substring(0, jsonPath.length - 1);
16+
17+
const h = Object.entries(state.layoutHashes).reduce(
18+
(acc, [path, pathHash]) =>
19+
jsonPath.startsWith(path.substring(0, path.length - 1))
20+
? (pathHash as number) + acc
21+
: acc,
22+
0
23+
);
24+
return [c, c.props, h];
1225
};
1326

1427
export function selectDashPropsEqualityFn(
15-
[c, p]: SelectDashProps,
16-
[oc, op]: SelectDashProps
28+
[_, __, hash]: SelectDashProps,
29+
[___, ____, previousHash]: SelectDashProps
1730
) {
18-
return p === op && c === oc;
31+
// Only need to compare the hash as any change is summed up
32+
return hash === previousHash;
1933
}
2034

2135
export function selectConfig(state: any) {

0 commit comments

Comments
 (0)