From 45281b6b3f6bfe69ceb2450c2c48961e2891d2c9 Mon Sep 17 00:00:00 2001 From: Tim Dorr Date: Mon, 23 Dec 2019 21:16:12 -0500 Subject: [PATCH 1/3] 4.0.5 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1a2d4a32c4..892a707bf0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "redux", - "version": "4.0.4", + "version": "4.0.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 6dc69e8d77..d8bafaa9d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "redux", - "version": "4.0.4", + "version": "4.0.5", "description": "Predictable state container for JavaScript apps", "license": "MIT", "homepage": "http://redux.js.org", From 8c11bbd082894b057639a9bb03f80b2d12bd8bbb Mon Sep 17 00:00:00 2001 From: Moshe Zemah Date: Mon, 3 Aug 2020 18:15:00 +0300 Subject: [PATCH 2/3] Notify listeners (subscribers) on next frame if needed --- src/createStore.js | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/createStore.js b/src/createStore.js index cef9a2ecae..35cf61b0ef 100644 --- a/src/createStore.js +++ b/src/createStore.js @@ -62,6 +62,8 @@ export default function createStore(reducer, preloadedState, enhancer) { let currentListeners = [] let nextListeners = currentListeners let isDispatching = false + var isNotifyListenersNextFrame = false + var alreadyNotifingListenersOnNextFrame = false /** * This makes a shallow copy of currentListeners so we can use @@ -156,6 +158,18 @@ export default function createStore(reducer, preloadedState, enhancer) { } } + /** + * + * @param {boolean} shouldNotifyOnNextFrame A boolean to configure the store + * to notify the listeners only on the next frame or after every dispatch. + * The state still keep changing between dispatches, only listeners (subscribers to store) don't run. + * Set to true if listeners should be notified only once per frame. + * Set to false (default) if listeners should be notified after every dispatch + */ + function setNotifyListenersOnNextFrame(shouldNotifyOnNextFrame) { + isNotifyListenersNextFrame = shouldNotifyOnNextFrame + } + /** * Dispatches an action. It is the only way to trigger a state change. * @@ -207,10 +221,24 @@ export default function createStore(reducer, preloadedState, enhancer) { isDispatching = false } - const listeners = (currentListeners = nextListeners) - for (let i = 0; i < listeners.length; i++) { - const listener = listeners[i] - listener() + function notifyListeners() { + const listeners = (currentListeners = nextListeners) + for (let i = 0; i < listeners.length; i++) { + const listener = listeners[i] + listener() + } + } + + if (isNotifyListenersNextFrame) { + if (!alreadyNotifingListenersOnNextFrame) { + alreadyNotifingListenersOnNextFrame = true + window.requestAnimationFrame(() => { + notifyListeners() + alreadyNotifingListenersOnNextFrame = false + }) + } + } else { + notifyListeners() } return action @@ -275,7 +303,7 @@ export default function createStore(reducer, preloadedState, enhancer) { [$$observable]() { return this - } + }, } } @@ -289,6 +317,7 @@ export default function createStore(reducer, preloadedState, enhancer) { subscribe, getState, replaceReducer, - [$$observable]: observable + setNotifyListenersOnNextFrame, + [$$observable]: observable, } } From 0faedaf73c289f5363ebce83750af966ef67644e Mon Sep 17 00:00:00 2001 From: Moshe Zemah Date: Mon, 3 Aug 2020 18:19:43 +0300 Subject: [PATCH 3/3] Notify listeners (subscribers) on next frame if needed --- src/createStore.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/createStore.js b/src/createStore.js index 35cf61b0ef..ac44aff2bd 100644 --- a/src/createStore.js +++ b/src/createStore.js @@ -303,7 +303,7 @@ export default function createStore(reducer, preloadedState, enhancer) { [$$observable]() { return this - }, + } } } @@ -318,6 +318,6 @@ export default function createStore(reducer, preloadedState, enhancer) { getState, replaceReducer, setNotifyListenersOnNextFrame, - [$$observable]: observable, + [$$observable]: observable } }