Skip to content
This repository has been archived by the owner on Jun 4, 2024. It is now read-only.

Renderer regression #140

Merged
merged 10 commits into from
Mar 25, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 73 additions & 81 deletions src/TreeContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,77 +75,6 @@ class TreeContainer extends Component {
);
}

getLoadingState() {
const {
_dashprivate_layout: layout,
_dashprivate_requestQueue: requestQueue
} = this.props;

const ids = this.isDeepStateElement() ?
this.getNestedIds() :
(layout && layout.props.id ?
[layout.props.id] :
[]);

let isLoading = false;
let loadingProp;
let loadingComponent;

if (requestQueue) {
forEach(r => {
const controllerId = isNil(r.controllerId) ? '' : r.controllerId;
if (r.status === 'loading' && any(id => contains(id, controllerId), ids)) {
isLoading = true;
[loadingComponent, loadingProp] = r.controllerId.split('.');
}
}, requestQueue);
}

// Set loading state
return {
is_loading: isLoading,
prop_name: loadingProp,
component_name: loadingComponent,
};
}

getNestedIds() {
const {
_dashprivate_layout: layout
} = this.props;

const ids = [];
const queue = [layout];

while (queue.length) {
const elementLayout = queue.shift();

const props = elementLayout &&
elementLayout.props;

if (!props) {
continue;
}

const { children, id } = props;

if (id) {
ids.push(id);
}

if (children) {
const filteredChildren = filter(
child => !isSimpleComponent(child) && !Registry.resolve(child.type, child.namespace)._dashprivate_deepstate,
Array.isArray(children) ? children : [children]
);

queue.push(...filteredChildren);
}
}

return ids;
}

getSetProps() {
return newProps => {
const {
Expand Down Expand Up @@ -184,16 +113,10 @@ class TreeContainer extends Component {
}

shouldComponentUpdate(nextProps) {
const { _dashprivate_layout, _dashprivate_requestQueue } = nextProps;
const { _dashprivate_layout, _dashprivate_loadingState } = nextProps;

return _dashprivate_layout !== this.props._dashprivate_layout ||
(this.isDeepStateElement() && _dashprivate_requestQueue !== this.props._dashprivate_requestQueue);
}

isDeepStateElement() {
const _dashprivate_layout = this.props._dashprivate_layout;

return Registry.resolve(_dashprivate_layout.type, _dashprivate_layout.namespace)._dashprivate_deepstate;
_dashprivate_loadingState.is_loading !== this.props._dashprivate_loadingState.is_loading;
}

getLayoutProps() {
Expand All @@ -203,15 +126,16 @@ class TreeContainer extends Component {
render() {
const {
_dashprivate_dispatch,
_dashprivate_layout
_dashprivate_layout,
_dashprivate_requestQueue
} = this.props;

const layoutProps = this.getLayoutProps();

const children = this.getChildren(layoutProps.children);
const setProps = this.getSetProps(_dashprivate_dispatch);

const loadingState = this.getLoadingState();
const loadingState = getLoadingState(_dashprivate_layout, _dashprivate_requestQueue);

return this.getComponent(
_dashprivate_layout, children, loadingState, setProps);
Expand All @@ -222,6 +146,7 @@ TreeContainer.propTypes = {
_dashprivate_dependencies: PropTypes.any,
_dashprivate_dispatch: PropTypes.func,
_dashprivate_layout: PropTypes.object,
_dashprivate_loadingState: PropTypes.object,
_dashprivate_paths: PropTypes.any,
_dashprivate_requestQueue: PropTypes.object,
};
Expand All @@ -243,11 +168,78 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
_dashprivate_dependencies: stateProps.dependencies,
_dashprivate_dispatch: dispatchProps.dispatch,
_dashprivate_layout: ownProps._dashprivate_layout,
_dashprivate_loadingState: getLoadingState(ownProps._dashprivate_layout, stateProps.requestQueue),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calculating the loadingState upfront instead of in the render function -- this allows to block/allow re-renderer based on loading state in shouldComponentUpdate

_dashprivate_paths: stateProps.paths,
_dashprivate_requestQueue: stateProps.requestQueue,
};
}

function getLoadingState(layout, requestQueue) {
const ids = isDeepStateElement(layout) ?
getNestedIds() :
(layout && layout.props.id ?
[layout.props.id] :
[]);

let isLoading = false;
let loadingProp;
let loadingComponent;

if (requestQueue) {
forEach(r => {
const controllerId = isNil(r.controllerId) ? '' : r.controllerId;
if (r.status === 'loading' && any(id => contains(id, controllerId), ids)) {
isLoading = true;
[loadingComponent, loadingProp] = r.controllerId.split('.');
}
}, requestQueue);
}

// Set loading state
return {
is_loading: isLoading,
prop_name: loadingProp,
component_name: loadingComponent,
};
}

function getNestedIds(layout) {
const ids = [];
const queue = [layout];

while (queue.length) {
const elementLayout = queue.shift();

const props = elementLayout &&
elementLayout.props;

if (!props) {
continue;
}

const { children, id } = props;

if (id) {
ids.push(id);
}

if (children) {
const filteredChildren = filter(
child => !isSimpleComponent(child) && !Registry.resolve(child.type, child.namespace)._dashprivate_deepstate,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isDeepStateElement

Array.isArray(children) ? children : [children]
);

queue.push(...filteredChildren);
}
}

return ids;
}

function isDeepStateElement(layout) {
return Registry.resolve(layout.type, layout.namespace)._dashprivate_deepstate;
}

export const AugmentedTreeContainer = connect(mapStateToProps, mapDispatchToProps, mergeProps)(TreeContainer);

export default AugmentedTreeContainer;