From b4e0cd8683e97a0572eadbc44eec6da53826dce7 Mon Sep 17 00:00:00 2001 From: nmccready Date: Tue, 28 Aug 2018 10:44:37 -0400 Subject: [PATCH 1/5] feature: delay can now be a function where the value can be derrived from props --- packages/debounce-handler/src/index.js | 4 +++- .../test/__snapshots__/index.js.snap | 10 ++++++++++ packages/debounce-handler/test/index.js | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/debounce-handler/src/index.js b/packages/debounce-handler/src/index.js index b1ddffe..5983196 100644 --- a/packages/debounce-handler/src/index.js +++ b/packages/debounce-handler/src/index.js @@ -7,9 +7,11 @@ const debounceHandler = (handlerName, delay, leadingCall) => (Target) => { constructor (props, context) { super(props, context) + const delayValue = typeof delay === 'function' ? delay(props) : delay; + this.debouncedPropInvoke = debounce( (...args) => this.props[handlerName](...args), - delay, + delayValue, leadingCall ) diff --git a/packages/debounce-handler/test/__snapshots__/index.js.snap b/packages/debounce-handler/test/__snapshots__/index.js.snap index aeb5524..edfb7c7 100644 --- a/packages/debounce-handler/test/__snapshots__/index.js.snap +++ b/packages/debounce-handler/test/__snapshots__/index.js.snap @@ -62,6 +62,16 @@ Array [ ] `; +exports[`debounceHandler should pass \`delay\` option to \`just-debounce-it\` via props 1`] = ` +Array [ + Array [ + [Function], + 75, + undefined, + ], +] +`; + exports[`debounceHandler should pass \`leadingCall\` option to \`just-debounce-it\` 1`] = ` Array [ Array [ diff --git a/packages/debounce-handler/test/index.js b/packages/debounce-handler/test/index.js index 564ce79..fba6c9b 100644 --- a/packages/debounce-handler/test/index.js +++ b/packages/debounce-handler/test/index.js @@ -77,6 +77,20 @@ describe('debounceHandler', () => { expect(mockJustDebounce.mock.calls).toMatchSnapshot() }) + it('should pass `delay` option to `just-debounce-it` via props', () => { + const EnhancedTarget = debounceHandler('testHandler', (props) => + props.debounce)(Target) + const mockTestHandler = jest.fn() + const wrapper = mount( + + ) + const testHandler = wrapper.find(Target).prop('testHandler') + + testHandler() + + expect(mockJustDebounce.mock.calls).toMatchSnapshot() + }) + it('should pass `leadingCall` option to `just-debounce-it`', () => { const EnhancedTarget = debounceHandler('testHandler', 75, true)(Target) const mockTestHandler = jest.fn() From cec49d3a382e961857705bd3bfc21b979cb3c5f0 Mon Sep 17 00:00:00 2001 From: nmccready Date: Tue, 28 Aug 2018 13:04:07 -0400 Subject: [PATCH 2/5] fix lint --- packages/debounce-handler/src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/debounce-handler/src/index.js b/packages/debounce-handler/src/index.js index 5983196..f72dfd7 100644 --- a/packages/debounce-handler/src/index.js +++ b/packages/debounce-handler/src/index.js @@ -7,7 +7,7 @@ const debounceHandler = (handlerName, delay, leadingCall) => (Target) => { constructor (props, context) { super(props, context) - const delayValue = typeof delay === 'function' ? delay(props) : delay; + const delayValue = typeof delay === 'function' ? delay(props) : delay this.debouncedPropInvoke = debounce( (...args) => this.props[handlerName](...args), From 9f2d643973bc91add154b6ff7ccf2100b9615aaa Mon Sep 17 00:00:00 2001 From: nmccready Date: Tue, 28 Aug 2018 15:35:47 -0400 Subject: [PATCH 3/5] throttle updated get debounce features and fixes --- packages/throttle-handler/src/index.js | 14 +++- .../test/__snapshots__/index.js.snap | 80 ++++++++----------- packages/throttle-handler/test/index.js | 38 +++++++-- 3 files changed, 74 insertions(+), 58 deletions(-) diff --git a/packages/throttle-handler/src/index.js b/packages/throttle-handler/src/index.js index 53b7a22..3dd12e2 100644 --- a/packages/throttle-handler/src/index.js +++ b/packages/throttle-handler/src/index.js @@ -7,21 +7,27 @@ const throttleHandler = (handlerName, interval, leadingCall) => (Target) => { constructor (props, context) { super(props, context) - const throttled = throttle(props[handlerName], interval, leadingCall) + const intervalValue = typeof interval === 'function' ? interval(props) : interval - this[handlerName] = (e, ...rest) => { + this.throttlePropInvoke = throttle( + (...args) => this.props[handlerName](...args), + intervalValue, + leadingCall + ) + + this.handler = (e, ...rest) => { if (e && typeof e.persist === 'function') { e.persist() } - return throttled(e, ...rest) + return this.throttlePropInvoke(e, ...rest) } } render () { return createElement(Target, { ...this.props, - [handlerName]: this[handlerName] + [handlerName]: this.handler }) } } diff --git a/packages/throttle-handler/test/__snapshots__/index.js.snap b/packages/throttle-handler/test/__snapshots__/index.js.snap index 4e11117..14d6d93 100644 --- a/packages/throttle-handler/test/__snapshots__/index.js.snap +++ b/packages/throttle-handler/test/__snapshots__/index.js.snap @@ -19,19 +19,19 @@ exports[`throttleHandler display name should wrap display name in non-production exports[`throttleHandler should call \`e.persist()\` if it has been passed 1`] = ` Array [ Array [ - [MockFunction] { - "calls": Array [ - Array [], - ], - "results": Array [ - Object { - "isThrow": false, - "value": undefined, - }, - ], + Object { + "persist": [MockFunction] { + "calls": Array [ + Array [], + ], + "results": Array [ + Object { + "isThrow": false, + "value": undefined, + }, + ], + }, }, - undefined, - undefined, ], ] `; @@ -42,20 +42,30 @@ Array [ ] `; +exports[`throttleHandler should call actual handler during lifecycle 1`] = `Array []`; + +exports[`throttleHandler should call actual handler during lifecycle 2`] = ` +Array [ + Array [ + undefined, + ], +] +`; + +exports[`throttleHandler should pass \`delay\` option to \`just-throttle\` via props 1`] = ` +Array [ + Array [ + [Function], + 75, + undefined, + ], +] +`; + exports[`throttleHandler should pass \`interval\` option to \`just-throttle\` 1`] = ` Array [ Array [ - [MockFunction] { - "calls": Array [ - Array [], - ], - "results": Array [ - Object { - "isThrow": false, - "value": undefined, - }, - ], - }, + [Function], 75, undefined, ], @@ -65,17 +75,7 @@ Array [ exports[`throttleHandler should pass \`leadingCall\` option to \`just-throttle\` 1`] = ` Array [ Array [ - [MockFunction] { - "calls": Array [ - Array [], - ], - "results": Array [ - Object { - "isThrow": false, - "value": undefined, - }, - ], - }, + [Function], 75, true, ], @@ -85,18 +85,6 @@ Array [ exports[`throttleHandler should pass handler arguments through 1`] = ` Array [ Array [ - [MockFunction] { - "calls": Array [ - Array [], - ], - "results": Array [ - Object { - "isThrow": false, - "value": undefined, - }, - ], - }, - undefined, undefined, ], ] diff --git a/packages/throttle-handler/test/index.js b/packages/throttle-handler/test/index.js index 25f198e..f20320f 100644 --- a/packages/throttle-handler/test/index.js +++ b/packages/throttle-handler/test/index.js @@ -8,7 +8,7 @@ describe('throttleHandler', () => { let throttleHandler = null beforeEach(() => { - mockJustThrottle = jest.fn(() => () => {}) + mockJustThrottle = jest.fn(cb => cb) jest.mock('just-throttle', () => mockJustThrottle) jest.resetModules() @@ -27,11 +27,22 @@ describe('throttleHandler', () => { ) const testHandler = wrapper.find(Target).prop('testHandler') - testHandler() - mockTestHandler() + expect(mockTestHandler.mock.calls).toMatchSnapshot() + }) - expect(mockJustThrottle.mock.calls).toMatchSnapshot() + it('should call actual handler during lifecycle', () => { + const EnhancedTarget = throttleHandler('testHandler')(Target) + const mockTestHandlerInitial = jest.fn() + const mockTestHandlerUpdated = jest.fn() + const wrapper = mount( + + ) + wrapper.setProps({testHandler: mockTestHandlerUpdated}) + const testHandler = wrapper.find(Target).prop('testHandler') + testHandler() + expect(mockTestHandlerInitial.mock.calls).toMatchSnapshot() + expect(mockTestHandlerUpdated.mock.calls).toMatchSnapshot() }) it('should call `e.persist()` if it has been passed', () => { @@ -44,9 +55,8 @@ describe('throttleHandler', () => { const testHandler = wrapper.find(Target).prop('testHandler') testHandler({ persist: mockPersist }) - mockTestHandler() - expect(mockJustThrottle.mock.calls).toMatchSnapshot() + expect(mockTestHandler.mock.calls).toMatchSnapshot() expect(mockPersist.mock.calls).toMatchSnapshot() }) @@ -59,7 +69,20 @@ describe('throttleHandler', () => { const testHandler = wrapper.find(Target).prop('testHandler') testHandler() - mockTestHandler() + + expect(mockJustThrottle.mock.calls).toMatchSnapshot() + }) + + it('should pass `delay` option to `just-throttle` via props', () => { + const EnhancedTarget = throttleHandler('testHandler', (props) => + props.throttle)(Target) + const mockTestHandler = jest.fn() + const wrapper = mount( + + ) + const testHandler = wrapper.find(Target).prop('testHandler') + + testHandler() expect(mockJustThrottle.mock.calls).toMatchSnapshot() }) @@ -73,7 +96,6 @@ describe('throttleHandler', () => { const testHandler = wrapper.find(Target).prop('testHandler') testHandler() - mockTestHandler() expect(mockJustThrottle.mock.calls).toMatchSnapshot() }) From a4f76aa86305120c15caa1dc6a0b391fbaca5584 Mon Sep 17 00:00:00 2001 From: nmccready Date: Tue, 28 Aug 2018 16:15:51 -0400 Subject: [PATCH 4/5] Demo and Documentation/Readme updates --- packages/debounce-handler/demo/index.js | 35 +++++++++++++++++-- packages/debounce-handler/readme.md | 41 ++++++++++++++++++---- packages/throttle-handler/demo/index.js | 35 +++++++++++++++++-- packages/throttle-handler/readme.md | 45 +++++++++++++++++++------ 4 files changed, 134 insertions(+), 22 deletions(-) diff --git a/packages/debounce-handler/demo/index.js b/packages/debounce-handler/demo/index.js index 82d1598..2cb800e 100644 --- a/packages/debounce-handler/demo/index.js +++ b/packages/debounce-handler/demo/index.js @@ -3,17 +3,46 @@ import { compose, withState, withHandlers } from 'recompose' import debounceHandler from '../src/' -const Demo = ({ count, onButtonClick }) => ( -
+const Demo = ({ count, onButtonClick, label }) => ( +
+ {label || ''}

{count}

) -export default compose( +const Demo1 = compose( withState('count', 'setCount', 0), withHandlers({ onButtonClick: ({ count, setCount }) => () => setCount(count + 1) }), debounceHandler('onButtonClick', 300) )(Demo) + +const Demo2 = compose( + withState('count', 'setCount', 0), + withHandlers({ + onButtonClick: ({ count, setCount }) => () => setCount(count + 1) + }), + debounceHandler('onButtonClick', (props) => props.debounce || 0) +)(Demo) + +const MainDemo = () => ( +
+ + + + +
+) + +export default MainDemo diff --git a/packages/debounce-handler/readme.md b/packages/debounce-handler/readme.md index dcc4158..4467c01 100644 --- a/packages/debounce-handler/readme.md +++ b/packages/debounce-handler/readme.md @@ -17,7 +17,7 @@ yarn add @hocs/debounce-handler ```js debounceHandler( handlerName: string, - delay?: number, + delay?: number|function, leadingCall?: boolean ): HigherOrderComponent ``` @@ -27,20 +27,49 @@ import React from 'react'; import { compose, withState, withHandlers } from 'recompose'; import debounceHandler from '@hocs/debounce-handler'; -const Demo = ({ count, onButtonClick }) => ( -
+const Demo = ({ count, onButtonClick, label }) => ( +
+ {label || ''}

{count}

-); +) -export default compose( +const Demo1 = compose( withState('count', 'setCount', 0), withHandlers({ onButtonClick: ({ count, setCount }) => () => setCount(count + 1) }), debounceHandler('onButtonClick', 300) -)(Demo); +)(Demo) + +const Demo2 = compose( + withState('count', 'setCount', 0), + withHandlers({ + onButtonClick: ({ count, setCount }) => () => setCount(count + 1) + }), + debounceHandler('onButtonClick', (props) => props.debounce || 0) +)(Demo) + +const MainDemo = () => ( +
+ + + + +
+) + +export default MainDemo ``` :tv: [Check out live demo](https://codesandbox.io/s/qlmk8mlvk4). diff --git a/packages/throttle-handler/demo/index.js b/packages/throttle-handler/demo/index.js index b42e3ff..d14b1a6 100644 --- a/packages/throttle-handler/demo/index.js +++ b/packages/throttle-handler/demo/index.js @@ -3,17 +3,46 @@ import { compose, withState, withHandlers } from 'recompose' import throttleHandler from '../src/' -const Demo = ({ count, onButtonClick }) => ( -
+const Demo = ({ count, onButtonClick, label }) => ( +
+ {label || ''}

{count}

) -export default compose( +const Demo1 = compose( withState('count', 'setCount', 0), withHandlers({ onButtonClick: ({ count, setCount }) => () => setCount(count + 1) }), throttleHandler('onButtonClick', 1000) )(Demo) + +const Demo2 = compose( + withState('count', 'setCount', 0), + withHandlers({ + onButtonClick: ({ count, setCount }) => () => setCount(count + 1) + }), + throttleHandler('onButtonClick', (props) => props.debounce || 0) +)(Demo) + +const MainDemo = () => ( +
+ + + + +
+) + +export default MainDemo diff --git a/packages/throttle-handler/readme.md b/packages/throttle-handler/readme.md index 6901ed9..16b272b 100644 --- a/packages/throttle-handler/readme.md +++ b/packages/throttle-handler/readme.md @@ -17,30 +17,55 @@ yarn add @hocs/throttle-handler ```js throttleHandler( handlerName: string, - interval?: number, + interval?: number|function, leadingCall?: boolean ): HigherOrderComponent ``` ```js -import React from 'react'; -import { compose, withState, withHandlers } from 'recompose'; -import throttleHandler from '@hocs/throttle-handler'; - -const Demo = ({ count, onButtonClick }) => ( -
+const Demo = ({ count, onButtonClick, label }) => ( +
+ {label || ''}

{count}

-); +) -export default compose( +const Demo1 = compose( withState('count', 'setCount', 0), withHandlers({ onButtonClick: ({ count, setCount }) => () => setCount(count + 1) }), throttleHandler('onButtonClick', 1000) -)(Demo); +)(Demo) + +const Demo2 = compose( + withState('count', 'setCount', 0), + withHandlers({ + onButtonClick: ({ count, setCount }) => () => setCount(count + 1) + }), + throttleHandler('onButtonClick', (props) => props.debounce || 0) +)(Demo) + +const MainDemo = () => ( +
+ + + + +
+) + +export default MainDemo ``` :tv: [Check out live demo](https://codesandbox.io/s/q96856wkow). From dcb742f8ca5e7f5042d18ebd2467042b4b5f052f Mon Sep 17 00:00:00 2001 From: nmccready Date: Tue, 28 Aug 2018 16:17:44 -0400 Subject: [PATCH 5/5] props.debounce to props.throttle in Demo and docs --- packages/throttle-handler/demo/index.js | 4 ++-- packages/throttle-handler/readme.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/throttle-handler/demo/index.js b/packages/throttle-handler/demo/index.js index d14b1a6..f5d4032 100644 --- a/packages/throttle-handler/demo/index.js +++ b/packages/throttle-handler/demo/index.js @@ -24,7 +24,7 @@ const Demo2 = compose( withHandlers({ onButtonClick: ({ count, setCount }) => () => setCount(count + 1) }), - throttleHandler('onButtonClick', (props) => props.debounce || 0) + throttleHandler('onButtonClick', (props) => props.throttle || 0) )(Demo) const MainDemo = () => ( @@ -40,7 +40,7 @@ const MainDemo = () => ( } - +
) diff --git a/packages/throttle-handler/readme.md b/packages/throttle-handler/readme.md index 16b272b..bf15c6e 100644 --- a/packages/throttle-handler/readme.md +++ b/packages/throttle-handler/readme.md @@ -44,7 +44,7 @@ const Demo2 = compose( withHandlers({ onButtonClick: ({ count, setCount }) => () => setCount(count + 1) }), - throttleHandler('onButtonClick', (props) => props.debounce || 0) + throttleHandler('onButtonClick', (props) => props.throttle || 0) )(Demo) const MainDemo = () => ( @@ -60,7 +60,7 @@ const MainDemo = () => ( } - +
)