From d9c5ad6aa4d68bee326415b298a18689c22da559 Mon Sep 17 00:00:00 2001
From: Paul Kaplan <pkaplan@media.mit.edu>
Date: Wed, 23 Jan 2019 15:56:23 -0500
Subject: [PATCH] Use curried style for HOC configuration

---
 .../sprite-selector/sprite-list.jsx           |  2 +-
 src/containers/stage-selector.jsx             |  2 +-
 src/containers/watermark.jsx                  |  2 +-
 src/lib/throttled-property-hoc.jsx            | 58 ++++++++++---------
 .../unit/util/throttled-property-hoc.test.jsx |  2 +-
 5 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/src/components/sprite-selector/sprite-list.jsx b/src/components/sprite-selector/sprite-list.jsx
index 2c9ad0ccc..e89898e47 100644
--- a/src/components/sprite-selector/sprite-list.jsx
+++ b/src/components/sprite-selector/sprite-list.jsx
@@ -12,7 +12,7 @@ import ThrottledPropertyHOC from '../../lib/throttled-property-hoc.jsx';
 
 import styles from './sprite-selector.css';
 
-const ThrottledSpriteSelectorItem = ThrottledPropertyHOC('asset', 500, SpriteSelectorItem);
+const ThrottledSpriteSelectorItem = ThrottledPropertyHOC('asset', 500)(SpriteSelectorItem);
 
 const SpriteList = function (props) {
     const {
diff --git a/src/containers/stage-selector.jsx b/src/containers/stage-selector.jsx
index 2da740388..988ebeddc 100644
--- a/src/containers/stage-selector.jsx
+++ b/src/containers/stage-selector.jsx
@@ -29,7 +29,7 @@ const dragTypes = [
 ];
 
 const DroppableThrottledStage = DropAreaHOC(dragTypes)(
-    ThrottledPropertyHOC('url', 500, StageSelectorComponent)
+    ThrottledPropertyHOC('url', 500)(StageSelectorComponent)
 );
 
 class StageSelector extends React.Component {
diff --git a/src/containers/watermark.jsx b/src/containers/watermark.jsx
index d0d60638c..fcb08ead2 100644
--- a/src/containers/watermark.jsx
+++ b/src/containers/watermark.jsx
@@ -65,7 +65,7 @@ const mapStateToProps = state => {
 const ConnectedComponent = connect(
     mapStateToProps
 )(
-    ThrottledPropertyHOC('asset', 500, Watermark)
+    ThrottledPropertyHOC('asset', 500)(Watermark)
 );
 
 export default ConnectedComponent;
diff --git a/src/lib/throttled-property-hoc.jsx b/src/lib/throttled-property-hoc.jsx
index cd7cd8ed8..7e508dfbe 100644
--- a/src/lib/throttled-property-hoc.jsx
+++ b/src/lib/throttled-property-hoc.jsx
@@ -6,38 +6,44 @@ import React from 'react';
  * rendered value of a prop for comparison.
  * @param {string} propName the name of the prop to throttle updates from.
  * @param {string} throttleTime the minimum time between updates to that specific property.
- * @param {React.Component} WrappedComponent component who will not update for certain props.
- * @returns {React.Component} component with throttling behavior
+ * @returns {function} a function that accepts a component to wrap.
  */
-const ThrottledPropertyHOC = function (propName, throttleTime, WrappedComponent) {
-    class ThrottledPropertyWrapper extends React.Component {
-        shouldComponentUpdate (nextProps) {
-            for (const property in nextProps) {
-                if (property !== propName && this.props[property] !== nextProps[property]) {
-                    return true; // Always update if another property has changed
+const ThrottledPropertyHOC = function (propName, throttleTime) {
+    /**
+     * The function to be called with a React component to wrap it.
+     * @param {React.Component} WrappedComponent - Component to wrap with throttler.
+     * @returns {React.Component} the component wrapped with the throttler.
+     */
+    return function (WrappedComponent) {
+        class ThrottledPropertyWrapper extends React.Component {
+            shouldComponentUpdate (nextProps) {
+                for (const property in nextProps) {
+                    if (property !== propName && this.props[property] !== nextProps[property]) {
+                        return true; // Always update if another property has changed
+                    }
                 }
-            }
 
-            // If only that prop has changed, allow update to go to render based
-            // on _lastRenderedTime and _lastRenderTime are updated in render
-            if (nextProps[propName] !== this._lastRenderedValue &&
-                Date.now() - this._lastRenderTime > throttleTime
-            ) {
-                return true; // Allow this update to go to render
-            }
+                // If only that prop has changed, allow update to go to render based
+                // on _lastRenderedTime and _lastRenderTime are updated in render
+                if (nextProps[propName] !== this._lastRenderedValue &&
+                    Date.now() - this._lastRenderTime > throttleTime
+                ) {
+                    return true; // Allow this update to go to render
+                }
 
-            return false;
-        }
-        render () {
-            this._lastRenderTime = Date.now();
-            this._lastRenderedValue = this.props[propName];
-            return (
-                <WrappedComponent {...this.props} />
-            );
+                return false;
+            }
+            render () {
+                this._lastRenderTime = Date.now();
+                this._lastRenderedValue = this.props[propName];
+                return (
+                    <WrappedComponent {...this.props} />
+                );
+            }
         }
-    }
 
-    return ThrottledPropertyWrapper;
+        return ThrottledPropertyWrapper;
+    };
 };
 
 export default ThrottledPropertyHOC;
diff --git a/test/unit/util/throttled-property-hoc.test.jsx b/test/unit/util/throttled-property-hoc.test.jsx
index 37fca7022..c24f937a3 100644
--- a/test/unit/util/throttled-property-hoc.test.jsx
+++ b/test/unit/util/throttled-property-hoc.test.jsx
@@ -13,7 +13,7 @@ describe('VMListenerHOC', () => {
                 value={propToThrottle}
             />
         );
-        const WrappedComponent = ThrottledPropertyHOC('propToThrottle', throttleTime, Component);
+        const WrappedComponent = ThrottledPropertyHOC('propToThrottle', throttleTime)(Component);
 
         global.Date.now = () => 0;
 
-- 
GitLab