Hi,
I am using redux 1.0.0-rc.
I am sure this does not add any overhead to the redux initialization but I'd like to understand what is the intent behind the fact that the action @@redux/INIT is sent in both Store.js and in combineReducers.js.
Example:
var userReducer = function (state = {}, action) {
console.log('userReducer was called with state', state, 'and action', action)
return state;
}
var itemsReducer = function (state = [], action) {
console.log('itemsReducer was called with state', state, 'and action', action)
return state;
}
import { createStore, combineReducers } from 'redux'
var reducer = combineReducers({
user: userReducer,
items: itemsReducer
})
// Output:
// userReducer was called with state {} and action { type: '@@redux/INIT' }
// userReducer was called with state {} and action { type: 'a.2.e.i.j.9.e.j.y.v.i' }
// itemsReducer was called with state [] and action { type: '@@redux/INIT' }
// itemsReducer was called with state [] and action { type: 'i.l.j.c.a.4.z.3.3.d.i' }
var store = createStore(reducer)
// Output
// userReducer was called with state {} and action { type: '@@redux/INIT' }
// itemsReducer was called with state [] and action { type: '@@redux/INIT' }
Thanks!
The first invocation is combineReducers trying to test your reducer for bad patterns. Doing this ASAP helps us have nicer error messages.
The next time you get INIT is when it's actually initialized.
I thought indeed that the random action type was here to perform a reducer sanity check but I didn't knew that the init action was used for a similar purpose in combineReducers. Makes sense now.
Thanks @gaearon !
I am sort of having problem with this.
I am using following reducer stuff for managing my state:
/**
* Gets both local Browser storage and persisted items from Server.
*/
const getActiveNotificationsForUser = () => {
let localitems = getNotificationsFromBrowserStorage();
let persistedItems = getServerPersistedNotifications(); //This makes an Ajax call to server
return [
...localitems,
...persistedItems
];
};
const notifications = (state = getActiveNotificationsForUser(), action) => {
switch (action.type) {
case AppConstants.NEW_NOTIFICATIONS:
// code goes here
default:
return state;
}
});
As you can see that getActiveNotificationsForUser function makes an Ajax call to Server, so this @@redux/INIT thing is causing my Ajax to fire thrice.
I have done a workaround however:
const _INIT_ACTION_TYPE = "@@redux/INIT";
let _init_action_count = 0;
const notifications = (state = [], action) => {
if (action.type === _INIT_ACTION_TYPE) {
_init_action_count++;
if (_init_action_count > 1)
state = getActiveNotificationsForUser();
}
switch (action.type) {
case AppConstants.NEW_NOTIFICATIONS:
// code goes here
default:
return state;
}
}
My question to @gaearon : Is this approach appropriate ?
No, this is not how AJAX is Redux apps should work. Reducers should be pure and not cause side effects. You are doing an AJAX call from reducer, which is a side effect. I would suggest you to re-read the docs at http://redux.js.org/ and take a look at examples/async in this repo.
Good point.
I'm new to React/Redux and not sure if I'm not doing something wrong. But I'm having a component making an AJAX call on componentWillMount to fetch data from the server to render.
And the problem is that often second @@INIT is dispatched after I receive the response from the server. It comes with an empty (initial) state which is passed to the component props and I receive a blank screen as the result.
Please see this log produced by the reducer:

Am I doing something wrong? How can I solve this issue? Thanks!
@ihor I would ask that kind of thing over on Stack Overflow. Not many people are going to see a comment from nearly one year old issue :)
That's a good suggestion @timdorr. In case Google brings some else with a similar problem to this thread I posted a StackOverflow question here.
Most helpful comment
The first invocation is
combineReducerstrying to test your reducer for bad patterns. Doing this ASAP helps us have nicer error messages.The next time you get
INITis when it's actually initialized.