Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to preserve extra state slices in combineReducers #4288

Closed
antoinetissier opened this issue Feb 16, 2022 · 2 comments
Closed

Comments

@antoinetissier
Copy link

antoinetissier commented Feb 16, 2022

New Features

What is the new or updated feature that you are suggesting?

Add an option to preserve extra state slices in combineReducers, instead of systematically filtering them out which is the current behavior.
The signature could be:

combineReducers(reducersMap: ReducersMapObject, options?: {preserveExtraSlices?: boolean}): Reducer

Why should this feature be included?

A combined reducer obtained by calling combineReducers will filter out state slices whose keys are not represented in the reducers map:

import { combineReducers } from "redux";
const fooReducer = (state = "foo") => {
  return state;
};
const rootReducer = combineReducers({ foo: fooReducer });
console.log(rootReducer({ foo: "foo", bar: "bar" }, {type: "someAction"}));
// => {foo: "foo"} 
// bar is filtered out

This is nice in most cases where the state management is defined in a single place, as it provides safeguards.

However, this prevents from doing code splitting and extending the state through a storeEnhancer.

More context on our use case to illustrate this.
We have an application relying on module federation.
There is a host application and extensions, and we want to allow each extension to define its own state management and inject it in the host application through a storeEnhancer.
When the module federated application is loaded, all store enhancers from the different extensions are composed, and createStore is called:

// hostApplicationReducer is the result of a call to `combineReducers`
createStore(hostApplicationReducer, hostApplicationInitialState, storeEnhancersFromExtensions)

But the filtering in combineReducers prevents the state injection from working well.
We could use other approaches like reducer injection, but then extensions would not have control over the initial state and middlewares.

What docs changes are needed to explain this?

The new options argument would need to be documented.

@timdorr
Copy link
Member

timdorr commented Feb 16, 2022

Could you give a more concrete example? I'm not sure I understand how you'd have a state slice available before its reducer is available. It would seem dangerous to me to preload state before you have the code to handle that state, particularly if you have actions intending to manipulate it on load.

@markerikson
Copy link
Contributor

FWIW, we've had lots of discussions over the years about various customization options for combineReducers, and I think our historical answer has been "if you need to customize the behavior, use your own version of combineReducers". Conceptually it's a pretty simple function - it's basically _.mapValues(), and there's plenty of examples of writing your own (like https://gist.github.com/gaearon/ffd88b0e4f00b22c3159 ). Not saying a hard "no" right away, but this is certainly something that can be done yourself to fit your own needs.

@markerikson markerikson closed this as not planned Won't fix, can't repro, duplicate, stale Jun 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants