From d205fc816303a2ef90e0e489b9d5c162f32f99fa Mon Sep 17 00:00:00 2001 From: Ioannis Kokkinidis Date: Tue, 16 May 2023 13:50:47 +0300 Subject: [PATCH 1/3] Allow externally defined shouldComponentUpdate This commit allows the user to externally control immediate updates with a callback similar to `shouldComponentUpdate`. When that returns true, we can flush the debounced update, and immediately re-render. --- packages/react-debounce-render/src/index.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/react-debounce-render/src/index.tsx b/packages/react-debounce-render/src/index.tsx index 4d50ffa..28509dd 100644 --- a/packages/react-debounce-render/src/index.tsx +++ b/packages/react-debounce-render/src/index.tsx @@ -4,13 +4,17 @@ import { DebounceSettings } from 'lodash'; import hoistNonReactStatics from 'hoist-non-react-statics'; -function debounceRender(ComponentToDebounce: ComponentType, wait?: number, debounceArgs?: DebounceSettings): ComponentType { +function debounceRender(ComponentToDebounce: ComponentType, wait?: number, debounceArgs?: DebounceSettings, forceUpdateCondition?: (nextProps: T, nextState: S) => boolean): ComponentType { class DebouncedContainer extends Component { public static readonly displayName = `debounceRender(${ ComponentToDebounce.displayName || ComponentToDebounce.name || 'Component' })`; updateDebounced = _debounce(this.forceUpdate, wait, debounceArgs); shouldComponentUpdate() { - this.updateDebounced(); + if (typeof forceUpdateCondition === 'function' && forceUpdateCondition(nextProps, nextState)) { + this.updateDebounced.flush(); + } else { + this.updateDebounced(); + } return false; } From a4f948e6a7daa059e97b11d29558886e269670f3 Mon Sep 17 00:00:00 2001 From: Ioannis Kokkinidis Date: Tue, 16 May 2023 13:54:17 +0300 Subject: [PATCH 2/3] Added previous props and state to force update callback --- packages/react-debounce-render/src/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-debounce-render/src/index.tsx b/packages/react-debounce-render/src/index.tsx index 28509dd..b2374f7 100644 --- a/packages/react-debounce-render/src/index.tsx +++ b/packages/react-debounce-render/src/index.tsx @@ -4,13 +4,13 @@ import { DebounceSettings } from 'lodash'; import hoistNonReactStatics from 'hoist-non-react-statics'; -function debounceRender(ComponentToDebounce: ComponentType, wait?: number, debounceArgs?: DebounceSettings, forceUpdateCondition?: (nextProps: T, nextState: S) => boolean): ComponentType { +function debounceRender(ComponentToDebounce: ComponentType, wait?: number, debounceArgs?: DebounceSettings, forceUpdateCondition?: (prevProps: T, nextProps: T, prevState: S, nextState: S) => boolean): ComponentType { class DebouncedContainer extends Component { public static readonly displayName = `debounceRender(${ ComponentToDebounce.displayName || ComponentToDebounce.name || 'Component' })`; updateDebounced = _debounce(this.forceUpdate, wait, debounceArgs); shouldComponentUpdate() { - if (typeof forceUpdateCondition === 'function' && forceUpdateCondition(nextProps, nextState)) { + if (typeof forceUpdateCondition === 'function' && forceUpdateCondition(this.props, nextProps, this.state, nextState)) { this.updateDebounced.flush(); } else { this.updateDebounced(); From 3b960f68bdb49b4f55ab8a30b19ba74171798be0 Mon Sep 17 00:00:00 2001 From: Ioannis Kokkinidis Date: Tue, 16 May 2023 17:27:05 +0300 Subject: [PATCH 3/3] Making sure that we always have a debounced callback to flush --- packages/react-debounce-render/src/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react-debounce-render/src/index.tsx b/packages/react-debounce-render/src/index.tsx index b2374f7..9517a28 100644 --- a/packages/react-debounce-render/src/index.tsx +++ b/packages/react-debounce-render/src/index.tsx @@ -10,10 +10,9 @@ function debounceRender(ComponentToDebounce: ComponentType, wait?: number, updateDebounced = _debounce(this.forceUpdate, wait, debounceArgs); shouldComponentUpdate() { + this.updateDebounced(); if (typeof forceUpdateCondition === 'function' && forceUpdateCondition(this.props, nextProps, this.state, nextState)) { this.updateDebounced.flush(); - } else { - this.updateDebounced(); } return false; }