diff --git a/client/coral-framework/components/Slot.js b/client/coral-framework/components/Slot.js
index b1df6647a..f86d44eb1 100644
--- a/client/coral-framework/components/Slot.js
+++ b/client/coral-framework/components/Slot.js
@@ -4,19 +4,48 @@ import styles from './Slot.css';
import {connect} from 'react-redux';
import {getSlotElements} from 'coral-framework/helpers/plugins';
import omit from 'lodash/omit';
+import union from 'lodash/union';
+import isEqual from 'lodash/isEqual';
-function Slot ({fill, inline = false, className, reduxState, defaultComponent: DefaultComponent, ...rest}) {
- let children = getSlotElements(fill, reduxState, rest);
- const pluginConfig = reduxState.config.pluginConfig || {};
- if (children.length === 0 && DefaultComponent) {
- children = ;
+class Slot extends React.Component {
+ shouldComponentUpdate(next) {
+
+ // Prevent Slot from rerendering when only reduxState has changed and
+ // it does not result in a change of slot children.
+ const keys = union(Object.keys(this.props), Object.keys(next));
+ const changes = keys.filter((key) => this.props[key] !== next[key]);
+ if (changes.length === 1 && changes[0] === 'reduxState') {
+ const prevChildrenUuid = this.getChildren(this.props).map((child) => child.type.talkUuid);
+ const nextChildrenUuid = this.getChildren(next).map((child) => child.type.talkUuid);
+ return !isEqual(prevChildrenUuid, nextChildrenUuid);
+ }
+
+ // Prevent Slot from rerendering when no props has shallowly changed.
+ return changes.length !== 0;
}
- return (
-
- {children}
-
- );
+ getSlotProps({fill: _a, inline: _b, className: _c, reduxState: _d, defaultComponent_: _e, ...rest} = this.props) {
+ return rest;
+ }
+
+ getChildren(props = this.props) {
+ return getSlotElements(props.fill, props.reduxState, this.getSlotProps(props));
+ }
+
+ render() {
+ const {inline = false, className, reduxState, defaultComponent: DefaultComponent} = this.props;
+ let children = this.getChildren();
+ const pluginConfig = reduxState.config.pluginConfig || {};
+ if (children.length === 0 && DefaultComponent) {
+ children = ;
+ }
+
+ return (
+
+ {children}
+
+ );
+ }
}
Slot.propTypes = {
diff --git a/client/coral-framework/helpers/plugins.js b/client/coral-framework/helpers/plugins.js
index b2ca78142..7bebaa1f6 100644
--- a/client/coral-framework/helpers/plugins.js
+++ b/client/coral-framework/helpers/plugins.js
@@ -9,6 +9,7 @@ import {loadTranslations} from 'coral-framework/services/i18n';
import {injectReducers} from 'coral-framework/services/store';
import camelize from './camelize';
import plugins from 'pluginsConfig';
+import uuid from 'uuid/v4';
export function getSlotComponents(slot, reduxState, props = {}) {
const pluginConfig = reduxState.config.plugin_config || {};
@@ -100,7 +101,12 @@ function addMetaDataToSlotComponents() {
const slots = plugin.module.slots;
slots && Object.keys(slots).forEach((slot) => {
slots[slot].forEach((component) => {
+
+ // Attach plugin name to the component
component.talkPluginName = plugin.name;
+
+ // Attach uuid to the component
+ component.talkUuid = uuid();
});
});
});