{"action":"created","issue":{"url":"https://api.github.com/repos/gaearon/redux/issues/186","labels_url":"https://api.github.com/repos/gaearon/redux/issues/186/labels{/name}","comments_url":"https://api.github.com/repos/gaearon/redux/issues/186/comments","events_url":"https://api.github.com/repos/gaearon/redux/issues/186/events","html_url":"https://github.com/gaearon/redux/issues/186","id":91614454,"number":186,"title":"Anti-pattern: reacting to @@INIT action","user":{"login":"gaearon","id":810438,"avatar_url":"https://avatars.githubusercontent.com/u/810438?v=3","gravatar_id":"","url":"https://api.github.com/users/gaearon","html_url":"https://github.com/gaearon","followers_url":"https://api.github.com/users/gaearon/followers","following_url":"https://api.github.com/users/gaearon/following{/other_user}","gists_url":"https://api.github.com/users/gaearon/gists{/gist_id}","starred_url":"https://api.github.com/users/gaearon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gaearon/subscriptions","organizations_url":"https://api.github.com/users/gaearon/orgs","repos_url":"https://api.github.com/users/gaearon/repos","events_url":"https://api.github.com/users/gaearon/events{/privacy}","received_events_url":"https://api.github.com/users/gaearon/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/gaearon/redux/labels/docs","name":"docs","color":"5319e7"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":12,"created_at":"2015-06-28T16:35:15Z","updated_at":"2015-07-06T00:50:27Z","closed_at":null,"body":"In the new docs (#140) we should clarify that any actions prefixed with `@@` are *not* meant to be handled. For example, you should never try to handle `@@INIT`. We might enforce that by slightly randomizing names (e.g. `@@INIT_2hj3jh34`).\r\n\r\nHandling `@@INIT` manually will break hot reloading. It is invoked at every hot reload, so if you do your initial data transformation there, it won't work the second time.\r\n\r\nI've seen people using `@@INIT` to hydrate the plain objects received from the server into the Immutable state. Instead of handling `@@INIT`, you need to consider one of two options:\r\n\r\n* convert your whole plain object state to Immutable right away before passing it to Redux;\r\n* check if the `state` is a plain object and use `fromJS` before handling the action.\r\n\r\n```js\r\nfunction myReducer(state = {}, action) {\r\n  if (!isImmutable(state)) { // some kind of typeof check here?\r\n    state = Immutable.fromJS(state);\r\n  }\r\n\r\n  ...\r\n}\r\n```\r\n\r\nIt is easy to abstract this away with a `createImmutableReducer` function like this:\r\n\r\n```js\r\nexport default function createImmutableReducer(initialState, handlers) {\r\n  return (state = initialState, action) => {\r\n    if (!isImmutable(state)) {\r\n      // Hydrate server plain object state\r\n      state = Immutable.fromJS(state);\r\n    }\r\n\r\n    const handler = handlers[action.type];\r\n    if (handler) {\r\n      state = handler(state, action);\r\n    }\r\n\r\n    if (!isImmutable(state)) {\r\n      throw new Error('Reducers must return Immutable objects.');\r\n    }\r\n\r\n    return state;\r\n  };\r\n}\r\n```\r\n\r\nIt can then be used for creating reducers from `action constant -> handler` map."},"comment":{"url":"https://api.github.com/repos/gaearon/redux/issues/comments/118683308","html_url":"https://github.com/gaearon/redux/issues/186#issuecomment-118683308","issue_url":"https://api.github.com/repos/gaearon/redux/issues/186","id":118683308,"user":{"login":"acdlite","id":3624098,"avatar_url":"https://avatars.githubusercontent.com/u/3624098?v=3","gravatar_id":"","url":"https://api.github.com/users/acdlite","html_url":"https://github.com/acdlite","followers_url":"https://api.github.com/users/acdlite/followers","following_url":"https://api.github.com/users/acdlite/following{/other_user}","gists_url":"https://api.github.com/users/acdlite/gists{/gist_id}","starred_url":"https://api.github.com/users/acdlite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acdlite/subscriptions","organizations_url":"https://api.github.com/users/acdlite/orgs","repos_url":"https://api.github.com/users/acdlite/repos","events_url":"https://api.github.com/users/acdlite/events{/privacy}","received_events_url":"https://api.github.com/users/acdlite/received_events","type":"User","site_admin":false},"created_at":"2015-07-06T00:50:27Z","updated_at":"2015-07-06T00:50:27Z","body":"Maybe we should namespace the init type, like the transducer protocol does?\r\n\r\n```js\r\nexport const INIT = '@@redux/init';\r\n```"}}