fix: avoid-wasteful-renders (#1544)

* Avoid un-necessary redux state update for frequent actions

* Avoid un-necessary re-render when no change in props

Co-authored-by: kedar.netelixir <kedar.choudhary@netelixir.com>
This commit is contained in:
Kedarandkedar.netelixir authored and GitHub committed 2020-03-23 14:31:39 -04:00
1 parent e374fe2118
commit e41d339f5f
6 files changed
+96 -81

No files matched your search

@@ -2,15 +2,20 @@ import ViewportGrid from './ViewportGrid.js';
import { MODULE_TYPES } from '@ohif/core';
import { connect } from 'react-redux';
import { extensionManager } from './../../App.js';
import memoize from 'lodash/memoize';
const mapStateToProps = state => {
const getAvailableViewportModules = memoize(viewportModules => {
const availableViewportModules = {};
const viewportModules = extensionManager.modules[MODULE_TYPES.VIEWPORT];
viewportModules.forEach(moduleDefinition => {
availableViewportModules[moduleDefinition.extensionId] =
moduleDefinition.module;
});
return availableViewportModules;
});
const mapStateToProps = state => {
const viewportModules = extensionManager.modules[MODULE_TYPES.VIEWPORT];
const availableViewportModules = getAvailableViewportModules(viewportModules);
// TODO: Use something like state.plugins.defaultPlugin[MODULE_TYPES.VIEWPORT]
let defaultPlugin;
@@ -39,66 +39,68 @@ const ViewportGrid = function(props) {
});
}, [viewportData]);
const ViewportPanes = layout.viewports.map((layout, viewportIndex) => {
const displaySet = viewportData[viewportIndex];
const getViewportPanes = () =>
layout.viewports.map((layout, viewportIndex) => {
const displaySet = viewportData[viewportIndex];
if (!displaySet) {
return null;
}
if (!displaySet) {
return null;
}
const data = {
displaySet,
studies,
};
const data = {
displaySet,
studies,
};
// JAMES TODO:
// JAMES TODO:
// Use whichever plugin is currently in use in the panel
// unless nothing is specified. If nothing is specified
// and the display set has a plugin specified, use that.
//
// TODO: Change this logic to:
// - Plugins define how capable they are of displaying a SopClass
// - When updating a panel, ensure that the currently enabled plugin
// in the viewport is capable of rendering this display set. If not
// then use the most capable available plugin
const pluginName =
!layout.plugin && displaySet && displaySet.plugin
? displaySet.plugin
: layout.plugin;
// Use whichever plugin is currently in use in the panel
// unless nothing is specified. If nothing is specified
// and the display set has a plugin specified, use that.
//
// TODO: Change this logic to:
// - Plugins define how capable they are of displaying a SopClass
// - When updating a panel, ensure that the currently enabled plugin
// in the viewport is capable of rendering this display set. If not
// then use the most capable available plugin
const pluginName =
!layout.plugin && displaySet && displaySet.plugin
? displaySet.plugin
: layout.plugin;
const ViewportComponent = _getViewportComponent(
data, // Why do we pass this as `ViewportData`, when that's not really what it is?
viewportIndex,
children,
availablePlugins,
pluginName,
defaultPluginName
);
const ViewportComponent = _getViewportComponent(
data, // Why do we pass this as `ViewportData`, when that's not really what it is?
viewportIndex,
children,
availablePlugins,
pluginName,
defaultPluginName
);
return (
<ViewportPane
onDrop={({
viewportIndex,
StudyInstanceUID,
displaySetInstanceUID,
}) => {
setViewportData({
viewportIndex,
StudyInstanceUID,
displaySetInstanceUID,
});
}}
viewportIndex={viewportIndex} // Needed by `setViewportData`
className={classNames('viewport-container', {
active: activeViewportIndex === viewportIndex,
})}
key={viewportIndex}
>
{ViewportComponent}
</ViewportPane>
);
});
return (
<ViewportPane
onDrop={setViewportData}
viewportIndex={viewportIndex} // Needed by `setViewportData`
className={classNames('viewport-container', {
active: activeViewportIndex === viewportIndex,
})}
key={viewportIndex}
>
{ViewportComponent}
</ViewportPane>
);
});
const ViewportPanes = React.useMemo(getViewportPanes, [
layout,
viewportData,
studies,
children,
availablePlugins,
defaultPluginName,
setViewportData,
activeViewportIndex,
]);
return (
<div
@@ -4,6 +4,10 @@ import { Component } from 'react';
import { ConnectedViewportGrid } from './../components/ViewportGrid/index.js';
import PropTypes from 'prop-types';
import React from 'react';
import memoize from 'lodash/memoize';
import _values from 'lodash/values';
var values = memoize(_values);
class ViewerMain extends Component {
static propTypes = {
@@ -140,9 +144,7 @@ class ViewerMain extends Component {
render() {
const { viewportSpecificData } = this.props;
const viewportData = viewportSpecificData
? Object.values(viewportSpecificData)
: [];
const viewportData = values(viewportSpecificData);
return (
<div className="ViewerMain">