feat(StateListenerRegistry): add 'deepEquals' option

Adds an extra 'options' argument to the register method which
allows to use deep equality instead of a shallow one when comparing
the current and the previous selections.
This commit is contained in:
paweldomas 2020-07-15 13:22:56 -05:00 committed by Paweł Domas
parent 29366a0029
commit ad948bdbe2
1 changed files with 25 additions and 3 deletions

View File

@ -2,6 +2,7 @@
import type { Store } from 'redux';
import { equals } from './functions';
import logger from './logger';
/**
@ -37,6 +38,18 @@ type Listener
*/
type Selector = (state: Object, prevSelection: any) => any;
/**
* Options that can be passed to the register method.
*/
type RegistrationOptions = {
/**
* @property {boolean} [deepEquals=false] - whether or not a deep equals check should be performed on the selection
* returned by {@link Selector}.
*/
deepEquals: ?boolean
}
/**
* A type of a {@link Selector}-{@link Listener} association in which the
* {@code Listener} listens to changes in the values derived from a redux
@ -50,6 +63,11 @@ type SelectorListener = {
*/
listener: Listener,
/**
* The {@link RegistrationOptions} passed during the registration to be applied on the listener.
*/
options: ?RegistrationOptions,
/**
* The {@code Selector} which selects values whose changes are listened to
* by {@link listener}.
@ -94,8 +112,10 @@ class StateListenerRegistry {
= selectorListener.selector(
store.getState(),
prevSelection);
const useDeepEquals = selectorListener?.options?.deepEquals;
if (prevSelection !== selection) {
if ((useDeepEquals && !equals(prevSelection, selection))
|| (!useDeepEquals && prevSelection !== selection)) {
prevSelections.set(selectorListener, selection);
selectorListener.listener(selection, store, prevSelection);
}
@ -117,12 +137,14 @@ class StateListenerRegistry {
* @param {Function} listener - The listener to register with this
* {@code StateListenerRegistry} so that it gets invoked when the value
* returned by the specified {@code selector} changes.
* @param {RegistrationOptions} [options] - Any options to be applied to the registration.
* @returns {void}
*/
register(selector: Selector, listener: Listener) {
register(selector: Selector, listener: Listener, options: ?RegistrationOptions) {
this._selectorListeners.add({
listener,
selector
selector,
options
});
}