What is the initialState used for in Redux createStore function - redux

All:
When I read the source of Redux, in its createStore:
function createStore(reducer, initialState, enhancer) {
......
var currentState = initialState;
......
dispatch({ type: ActionTypes.INIT });
......
}
When create a new store, it sets currentState to initialState, and call reducer in init dispatch to update the default state value. I wonder: generally the currentStatew will be given a value from reducer, then what is the purpose of that initialState?
Thanks

Normally, just specify the initial state as reducer default argument, and let each reducer manage it for themselves.
However in some cases you want to “hydrate” the state with existing data. For example, you might have saved the whole state tree in a localStorage and want to load it from there on startup, or maybe you are rendering on the server, and want to load the initial state you saved on the server from the HTML.
In this case, the initialState to createStore() is useful because it lets you optionally hydrate some parts of the tree where you have pre-populated data. In this case, it would “win” to the reducer default state which is usually the behavior you would want. The parts of the state tree that exist in initialState would be used as is, and the missing parts would be retrieved from the reducers. This makes it possible to “restore” some parts of the state, but always re-initialize the others.
Hopefully this answer should provide a more in-depth explanation of this technique.

Related

NgRx reducer function with condition

I have a side effect that detects the browser language and dispatches a browserLanguageSupported action if it is a language that my application can handle.
Now I have following reducer function that only updates the states preferredLanguage property in case it is not defined already. This is important because there are other actions that update this state property and I do not want a late browserLanguageSupported action to overwrite such a state update.
export interface State {
preferredLanguage: AppLanguage | undefined;
rehydrationComplete: boolean;
}
export const initialState: State = {
preferredLanguage: undefined,
rehydrationComplete: false
};
export const reducer = createReducer(
initialState,
on(LanguageActions.browserLanguageSupported, (state, {browserLanguage}) => {
if (!state.preferredLanguage) {
return {...state, preferredLanguage: browserLanguage};
}
return state;
})
);
Now for my question: Is it good practice to have such a condition in a reducer operator? The function itself is still pure. But I am not sure if it is good design or if I should solve it differently, lets say by adding state slice selection in the side effect that dispatches this action.
Btw. the reason I am not setting it directly in the initial state is because I get the browser language from an angular service and I am not sure if it is even possible to set initial feature state from service injection?
Best regards,
Pascal
I would to this the same way, so you get a 👍 from me.
Adding a slice of the state into the effect just adds needless complexity.
The reducer contains the state, and it's OK to add logic to see if state needs to be updated or not.
Also, let's say you need to add this logic into another action/effect.
Having it in the reducer makes it easier to reuse if it's needed. Otherwise you end up with duplicate logic.
As long as the rejection (or mutation) of the data is irrelevant to the chain of actions & effects, this is absolutely valid.
However, it's worth noting that if the action in question triggers an effect which triggers an action, the triggered action will not know whether the data was rejected (or mutated) without checking the state—which is exactly what this pattern is attempting to avoid.
So, if you wanted to be able react to that rejection (or mutation), you would want to handle this in the effect. But, if you would proceed in exactly the same manner regardless of the result, then it belongs reducer.

What Redux mean by there is one particular function take the whole state of the application?

I just start learning how redux work :
What redux mean by there is one particular function take the whole state of the application and action is been dispatched and return the whole new state of the application?
is this is visible on Enterprise level application Single Page Application ERP system or I have misunderstood something?
also how the function be pure and change in the previous state " use ref of the previous state and add to it new data then return this as an object?
if it is not is that will not affect the speed of the system to copy each time the whole system state for ERP system?
the course in which I get this info 1
the course in which I get this info 2
Redux in general
In redux, your app's state is represented as a single object which is passed to your app.
This single object is constructed by a single function which is called reducer. This function takes the current state and current action as arguments and returns a new object which represents the new state changed after the action is reduced.
It's kinda similar to Array.prototype.reduce where you get current accumulator (current state) current array entry (current action) and return new accumulator (new state) depending on what is the current accumulator and entry (state and action).
Combining reducers
Nevertheless, this doesn't mean you need to put all of your app's logic in one function. Redux has a helper combineReducers to let you write reducers for different parts of your state and then combine them into single reducer that constructs a single state object.
For example for a blog app with posts and comments, you can use it like that:
import { combineReducers, createStore } from 'redux';
import postsReducer from './postReducer';
import commentsReducer from './commentsReducer';
const rootReducer = combineReducers({
posts: postsReducer,
comments: commentsReducer,
});
const store = createStore(rootReducer);
Where postReducer and commentsReducer are two separate reducers each handling their part of the state.

In Redux: how to store data from initial html to store? initialState or dispatch?

We have a dillema.
Certain data arrives through a template to our initial index.html page.
We put it on the window and the want to place it in the store.
Right now, we have something like this (psuedoish):
class App ... {
componentDidMount() {
this.props.setLoggedInUser(this.props.user);
// setLoggedInUser is a dispatch prop
}
}
<App user={window.user} />
option two is to just use initial state:
createStore(reducer, { user: window.user }, ...)
We had a lengthy discussion and can't agree if initialState is an anti-pattern or not.
Which is the correct way to implement this type of data loading?
I think initialState is not intended for such use. I would probably initialize it in reducer:
userReducer(state=window.user, action) ...
But that is under assumption that window.user is constant. If it is floating kind of thing, than I would probably go dispatch way, but not in componentDidMount, but in piece of code immediately following createStore
Using initialState when creating the store from bootstrapped data is the preferred way according to the documentation (see #2).
When bootstrapping data this way, you never get in a state where you're waiting for the store to apply the dispatched action. Another bonus is that you don't dispatch an action that isn't in relation to something happening in the UI.

How to update the state in redux without using mapDispatchToProps() method

I am trying to update the reducer state using :
store.dispatch(NameOftheReducer(data)).
It calls the Action creator but it does not update the reducer state. I dont want to create any React component from where i want to dispatch the state change. Is there any way to do so..Thanks in advance
Lets assume the store is stored stored somewhere global
then you can just
store.dispatch({
type: "SOME_ACTION",
value: "value"
})
if you have some actionCreator like:
function someAction(value) {
return {
type: "SOME_ACTION",
value: value
}
}
And and now you can use it with dispatch:
store.dispatch(someAction("some value"))
Did I missed something?
I think you misunderstood how component and redux state relates.
redux state change are done through actions regardless of which component is actually 'using' this state.
As long as you have an action creator defined somewhere, and you reducer handle the corresponding action.type, then you can use this action creator in whichever component.
There is no benefit of using store directly. store is stored in context, and it is generally considered bad practice using context. The nice thing about redux is that it takes care of this by giving you Provider and connect.
Except when initializing the app, you should always use mapDispatchToProps when you want to use action creators in your component.

How to handle cross-cutting concerns in redux reducers and actions

Given a use case like the one in this question:
Best way to update related state fields with split reducers?
What is the best practice for dealing with actions in reducers that depend on state outside of their own state? The author of the question above ended up just passing the entire state tree as a third argument to every reducer. This seems heavy-handed and risky. The Redux FAQ lists the following potential solutions:
If a reducer needs to know data from another slice of state, the state tree shape may need to be reorganized so that a single reducer is handling more of the data.
You may need to write some custom functions for handling some of these actions. This may require replacing combineReducers with your own top-level reducer function.
You can also use a utility such as reduce-reducers to run combineReducers to handle most actions, but also run a more specialized reducer for specific actions that cross state slices.
Async action creators such as redux-thunk have access to the entire state through getState(). An action creator can retrieve additional data from the state and put it in an action, so that each reducer has enough information to update its own state slice.
In my use case, I have an action "continue" that determines what page a user is allowed to go to in a multiple-form / multi-step process, and since this depends on pretty much the entire app state, I can't handle it in any of my child reducers. For now, I've pulled the store into the action creator. I use the current state of the store to calculate an action object that fires to my "page" reducer, which changes the active page. I will probably install redux-thunk and use getState() in this action creator, but I'm not committed to this approach yet.
I guess this isn't too bad of a solution since there is only one action (so far) that must be handled this way. I'm just wondering if there is a better solution, or if there is a way to re-structure my state and reducers to make it easier, or if what I'm doing is within best practices for Redux. If there are any similar examples out there, that would be helpful also.
To give some more context, my state tree currently looks like this:
{
order: order.result,
items: order.entities.items,
activePage: {
id: 'fulfillment'
// page info
},
pagesById: { // all the possible pages
fulfillment: {
id: 'fulfillment'
// page info
}
}
}
The active page is the page / section in which the user must enter data in order to proceed to the next page). Determining the active page almost always depends on the items state and sometimes depends on order state. The end result is an app where the user fills out a few forms in succession, hitting continue once the form is valid. On continue the app determines the next page needed and displays it, and so on.
EDIT: We've tried the approach of implementing a "global" reducer in combination with child reducers.
The implementation is like this...
const global = (currentState = initialState, action) => {
switch (action.type) {
default:
return currentState
}
}
const subReducers = combineReducers({
order,
meta
})
export default function (currentState = initialState, action) {
var nextState = global(currentState, action)
return subReducers(nextState, action)
}
The global reducer is first run on the whole app state, then the result of that is fed to the child reducers. I like the fact that I'm no longer putting a bunch of logic in action creators just to read different parts of state.
I believe this is in alignment with the principles of redux since every action still hits every reducer, and the order in which reducers are called is always the same. Any thoughts on this implementation?
EDIT: We are now using router libraries to handle the page state, so activePage and pagesById are gone.
If state.activePage depends of state.order and state.items, you may subscribe to the store and in case of modifications on "order" or "items" then dispatch a "checkPage" action which can set another active page if necessary. One way should to connect on a "top component" order and items, listen their values and change active page/redirect
Not easy to understand your concern, I hope my message will help. Good luck

Resources