Configuring slice‑specific filtering for Redux store subscriptions
0 reputation · 28 Feb 2020, 15:43 UTC
0 reputation · 28 Feb 2020, 15:43 UTC
Goal: Configure a Redux store so that subscription listeners are invoked only when a specific slice of the state tree changes, eliminating the need for manual equality checks inside each listener.
Constraint: Core Redux’s store.subscribe notifies listeners on every dispatch, regardless of whether the returned state reference or the targeted slice has changed, and there is no built‑in option to filter notifications by slice or to suppress calls when the slice is unchanged.
Uncertainty: While community middleware such as redux‑batched‑subscriptions or custom store enhancers can add slice‑specific filtering, it is unclear whether an official or recommended pattern exists for this behavior, or if future releases plan to incorporate it directly into the store API.
Questions: What official or community‑endorsed approaches provide slice‑specific subscription filtering without requiring listeners to perform their own equality checks? Is there any plan to add native slice‑filtering capabilities to Redux’s core store subscription mechanism?
34775 reputation · 28 Feb 2020, 20:35 UTC
The official way to receive notifications only when a chosen slice of the Redux state changes is to wrap store.subscribe with a selector function and a reference‑equality check. This pattern is documented in the Redux FAQ and is the basis for useSelector in React‑Redux.
store.subscribe fires after every dispatch; the core API has no built‑in filtering.useSelector (or connect) already implements selector‑based equality checks, so manual subscription filtering is rarely needed in React apps.const selectSlice = state => state.mySlice;Object.is (or a custom equality function) and only calls the listener when they differ.store.subscribe instead of the raw listener.useSelector(selectSlice, equalityFn) (or connect) which does the same work automatically.function observeStore(store, select, onChange) {
let current = select(store.getState());
return store.subscribe(() => {
const next = select(store.getState());
if (!Object.is(current, next)) {
const prev = current;
current = next;
onChange(prev, next);
}
});
}
// usage
const unsubscribe = observeStore(store, state => state.users, (prev, next) => {
console.log('users slice changed', prev, next);
});
useSelector do not re‑render on unrelated dispatches.Are you building a plain Redux application or a React‑Redux application? The recommendation shifts to useSelector for React projects, while the observeStore helper is the direct solution for plain Redux.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.