redux-utilities / redux-actions

Flux Standard Action utilities for Redux.
https://redux-actions.js.org
MIT License
6.51k stars 299 forks source link

No way to perform a custom merging with store's `preloadedState` over reducer's `defaultState` #260

Closed stomvi closed 1 year ago

stomvi commented 6 years ago

Am I missing something or there is still no way to customize init store by partially merge or fill server side or persistent storage data preloadedState into reducers' defatulState? For example, if I have a server-side data that is supplied to the store by preloadedState:

{
  "countyId": "5",
}

And the defaultState in reducers is:

{
  "sortBy": "created",
  "countyId": "1",
}

What I like to have in my store after init is like this:

{
  "sortBy": "created",
  "countyId": "5",
}

We may manually merge the data In typical reducers or use combineReducers to achieve partial hydration that are described as follows:

https://github.com/reactjs/redux/issues/433#issuecomment-129187414 https://github.com/reactjs/redux/issues/433#issuecomment-220124645

redux-actions returns the whole preloadedState and use it as the initial state of the store if preloadedState is not undefined.

Is there any way to customize init store in a more complex case?

mslipper commented 6 years ago

Hi @stomvi,

I've just been granted access to the repo and will start maintaining it going forward. I need a few days to get a clear understanding of the code and the project's roadmap. After that, I can answer your issue. Does this work for you?

stomvi commented 6 years ago

@mslipper, Yes and thank you. If I wasn't clear enough, the main goal of custom merging is in some cases that the server won't have to provide all the init state (I think most of the cases are) but the client-side code should have solid default state.

For example, a page that has a filter set with part of the filters contain their own default state. While working with router like react-router, the url may collect some filter queries after user clicks. Next time the same url is opened, filters may get it's own default state by merging the preloadedState and defaultState so that the backend won't have to provide all the filter state at once.

Some said to dispatch an init action as quickly as the components are loaded to set custom state to the store. Or combine preloadedState with defaultState before supplied to handleActions. Since it's a bad idea to handle @@INIT action (https://github.com/reactjs/redux/issues/186), by the former solution we have to dispatch a custom action which we might do this it in a whatever component's life cycle. The latter one we have to use preloadedState inside a reducer.js. These will all decrease the reusability of the code.

Currently I just use nested combineReducers like:

function searchMethod(state = SEARCH_METHOD_COUNTY, action) {
  // codes here
}

function countyId(state = false, action) {
  // ...my code
}

function staticData(state = {}) {
  // this state will be hydrated
}

const reducer = combineReducers({
  filter: combineReducers({
    searchMethod,
    countyId,
  }),
  staticData,
});

export default reducer;

It will help a lot If there is a good way to do this while using redux-actions.

alexander-heimbuch commented 1 year ago

I will close this issue for now. If this issue is still present please feel free to comment and reopen it :)