{"action":"created","issue":{"url":"https://api.github.com/repos/reactjs/redux/issues/1400","repository_url":"https://api.github.com/repos/reactjs/redux","labels_url":"https://api.github.com/repos/reactjs/redux/issues/1400/labels{/name}","comments_url":"https://api.github.com/repos/reactjs/redux/issues/1400/comments","events_url":"https://api.github.com/repos/reactjs/redux/issues/1400/events","html_url":"https://github.com/reactjs/redux/issues/1400","id":133640340,"number":1400,"title":"Is passing top-level state object to branch reducer an anti-pattern?","user":{"login":"pitaj","id":803701,"avatar_url":"https://avatars.githubusercontent.com/u/803701?v=3","gravatar_id":"","url":"https://api.github.com/users/pitaj","html_url":"https://github.com/pitaj","followers_url":"https://api.github.com/users/pitaj/followers","following_url":"https://api.github.com/users/pitaj/following{/other_user}","gists_url":"https://api.github.com/users/pitaj/gists{/gist_id}","starred_url":"https://api.github.com/users/pitaj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pitaj/subscriptions","organizations_url":"https://api.github.com/users/pitaj/orgs","repos_url":"https://api.github.com/users/pitaj/repos","events_url":"https://api.github.com/users/pitaj/events{/privacy}","received_events_url":"https://api.github.com/users/pitaj/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/reactjs/redux/labels/question","name":"question","color":"cc317c"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":8,"created_at":"2016-02-15T07:12:23Z","updated_at":"2016-02-15T21:42:17Z","closed_at":"2016-02-15T19:28:42Z","body":"I have a redux state where multiple branches' state demand on state of other branches. This means that I must last three entire state tree to each reducer, while the reducer only returns a single branch. \r\n\r\nIs this a bad thing to do? I don't see how it could lead to problems as long as a branch is not modifying data of other branches (which they aren't). "},"comment":{"url":"https://api.github.com/repos/reactjs/redux/issues/comments/184406378","html_url":"https://github.com/reactjs/redux/issues/1400#issuecomment-184406378","issue_url":"https://api.github.com/repos/reactjs/redux/issues/1400","id":184406378,"user":{"login":"naw","id":8030877,"avatar_url":"https://avatars.githubusercontent.com/u/8030877?v=3","gravatar_id":"","url":"https://api.github.com/users/naw","html_url":"https://github.com/naw","followers_url":"https://api.github.com/users/naw/followers","following_url":"https://api.github.com/users/naw/following{/other_user}","gists_url":"https://api.github.com/users/naw/gists{/gist_id}","starred_url":"https://api.github.com/users/naw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/naw/subscriptions","organizations_url":"https://api.github.com/users/naw/orgs","repos_url":"https://api.github.com/users/naw/repos","events_url":"https://api.github.com/users/naw/events{/privacy}","received_events_url":"https://api.github.com/users/naw/received_events","type":"User","site_admin":false},"created_at":"2016-02-15T21:42:16Z","updated_at":"2016-02-15T21:42:16Z","body":"There are two way of looking at your application:\r\n\r\n1. Given an action, what slices of state does it affect, and how?\r\n2. Given a slice of state, what actions affect it, and how?\r\n\r\nBoth are useful, and which is _more_ useful is really subjective. You have to try both and decide for yourself what works well for you and your team, or blindly choose to take someone's opinion.\r\n\r\nThe `redux` code itself works with either approach, although the `redux` docs (and flux in general) heavily encourage approach (2).\r\n\r\nLet's consider a concrete example:\r\n\r\nSuppose you have three domain objects: `friendRequests`, `chatMessages`, and `notifications`, and suppose your state-tree looks like this:\r\n\r\n```\r\n{\r\n  friendRequests: [],\r\n  chatMessages: [],\r\n  notifications: []\r\n}\r\n```\r\n\r\nWhen you receive a new `friendRequest`, you want to append it to the `friendRequests` array, and also create a `notification`. Similarly, when you receive a new `chatMessage`, you want to append it to the `chatMessages` array, and also create a `notification`.\r\n\r\nYou can model this with either the action-centric approach suggested in the article, or with a slice-centric approach as recommended in the redux docs.\r\n\r\nThe first action-specific way looks like this:\r\n\r\n````\r\nmainReducer = function(state, action) {\r\n  switch(action.type) {\r\n    when NEW_FRIEND_REQUEST:\r\n    return { ...state, friendRequests: state.friendRequests.concat(action.friendRequest), notifications: state.notifications.concat({ notification_type: 'friendRequest', action.friendRequest.id }) };\r\n    when NEW_CHAT_MESSAGE:\r\n      return { ...state, chatMessages: state.chatMessages.concat(action.chatMessage), notifications: state.notifications.concat({ notification_type: 'chatMessage', notification_id: action.chatMessage.id });\r\n  }\r\n}\r\n````\r\n\r\nYou can at a glance see that the `NEW FRIEND_REQUEST` action does 2 things to the state --- adds a friend request and adds a notification.  What you _can't_ see at a glance, is which actions affect `notifications` --- you have to look through _every_ action to determine that.\r\n\r\nThe second slice-centric way looks like this:\r\n\r\n````\r\nmainReducer = function(state, action) {\r\n  friendRequets =  switch(action.type) {\r\n    when NEW_FRIEND_REQUEST:\r\n      state.friendRequests.concat(action.friendRequest);\r\n      break\r\n    default:\r\n      friend_requests:\r\n      break;\r\n  }\r\n  chatMessages = switch(action.type) {\r\n    when NEW_CHAT_MESSAGE:\r\n      state.chatMessages.concat(action.chatMessage);\r\n      break;\r\n    default:\r\n      state.chatMessages;\r\n      break;\r\n   }\r\n  notifications = switch(action.type) {\r\n    when NEW_CHAT_MESSAGE:\r\n      state.notifications.concat({ notification_type: 'chatMessage', notification_id: action.chatMessage.id });\r\n      break;\r\n    when NEW_FRIEND_REQUEST:\r\n       state.notifications.concat({ notification_type: 'friendRequest', notification_id: action.friendRequst.id});\r\n       break;\r\n    default\r\n     state.notifications;\r\n     break;\r\n  }\r\n  return { friendRequests: friendRequests, chatMessages: chatMessages, notifications: notifications };\r\n}\r\n````\r\n\r\nYou can see at a glance that both `NEW_CHAT_MESSAGE` and `NEW_FRIEND_REQUEST` affect `notifications`, but you _can't_ see at a glance that `NEW_FRIEND_REQUEST` affects more than one slice of state.\r\n\r\nThese are completely isomorphic.  You can easily (albeit painstakingly) switch back and forth between the two implementations.   In fact, you could probably build a tool that could convert one to the other, or even visualize one as if it were the other.\r\n\r\nI do find it interesting that `redux` code itself is fully compatible with both approaches, yet heavily encourages the 2nd.  In other words, there is nothing about `redux` in and of itself that would push you one direction or the other."}}