{"action":"created","issue":{"url":"https://api.github.com/repos/kadirahq/react-komposer/issues/2","labels_url":"https://api.github.com/repos/kadirahq/react-komposer/issues/2/labels{/name}","comments_url":"https://api.github.com/repos/kadirahq/react-komposer/issues/2/comments","events_url":"https://api.github.com/repos/kadirahq/react-komposer/issues/2/events","html_url":"https://github.com/kadirahq/react-komposer/issues/2","id":124680539,"number":2,"title":"composer function re-run after every prop change","user":{"login":"arunoda","id":50838,"avatar_url":"https://avatars.githubusercontent.com/u/50838?v=3","gravatar_id":"","url":"https://api.github.com/users/arunoda","html_url":"https://github.com/arunoda","followers_url":"https://api.github.com/users/arunoda/followers","following_url":"https://api.github.com/users/arunoda/following{/other_user}","gists_url":"https://api.github.com/users/arunoda/gists{/gist_id}","starred_url":"https://api.github.com/users/arunoda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arunoda/subscriptions","organizations_url":"https://api.github.com/users/arunoda/orgs","repos_url":"https://api.github.com/users/arunoda/repos","events_url":"https://api.github.com/users/arunoda/events{/privacy}","received_events_url":"https://api.github.com/users/arunoda/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-01-04T00:19:27Z","updated_at":"2016-01-05T02:34:13Z","closed_at":null,"body":"Currently, composer function will re-run for every prop change. This is a continuation of the discussion started at: https://github.com/facebook/react/issues/3398#issuecomment-168518308"},"comment":{"url":"https://api.github.com/repos/kadirahq/react-komposer/issues/comments/168875176","html_url":"https://github.com/kadirahq/react-komposer/issues/2#issuecomment-168875176","issue_url":"https://api.github.com/repos/kadirahq/react-komposer/issues/2","id":168875176,"user":{"login":"ccorcos","id":1794527,"avatar_url":"https://avatars.githubusercontent.com/u/1794527?v=3","gravatar_id":"","url":"https://api.github.com/users/ccorcos","html_url":"https://github.com/ccorcos","followers_url":"https://api.github.com/users/ccorcos/followers","following_url":"https://api.github.com/users/ccorcos/following{/other_user}","gists_url":"https://api.github.com/users/ccorcos/gists{/gist_id}","starred_url":"https://api.github.com/users/ccorcos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ccorcos/subscriptions","organizations_url":"https://api.github.com/users/ccorcos/orgs","repos_url":"https://api.github.com/users/ccorcos/repos","events_url":"https://api.github.com/users/ccorcos/events{/privacy}","received_events_url":"https://api.github.com/users/ccorcos/received_events","type":"User","site_admin":false},"created_at":"2016-01-05T02:34:13Z","updated_at":"2016-01-05T02:34:13Z","body":"@arunoda, don't you think that this is still imperative programming? You've isolated the side-effect to a container component, but your entire UI isnt side-effect free anymore and is imperatively tied to the lifecycle of the components.\r\n\r\nTake this analogy. We used to do this:\r\n\r\n```js\r\nturnOn = (e) => {\r\n  e.target.addClass('on')\r\n}\r\nturnOff = (e) => {\r\n  e.target.removeClass('on')\r\n}\r\n```\r\nAnd now we do this:\r\n```js\r\nrender = (state, props) => {\r\n  return <div className={state.on ? 'on' : 'off'}></div>\r\n}\r\n```\r\nThe the second example, we just declare what we want and let React parse the component tree and handle any mutations.\r\n\r\nThe way you're proposing to fetch data in containers (and which I think just about everyone is doing) looks a lot like this:\r\n```js\r\ncomponentWillMount = () => {\r\n  fetchData()\r\n}\r\ncomponentWillUnmount = () => {\r\n  cleanup()\r\n}\r\n```\r\nThis is the same imperative style as before. What I think we should be doing is declaratively specifying what is needed and letting some other service parse and do all the imperative heavy lifting.\r\n\r\nRelay is a step in the right direction. But I think its pretty convoluted how the Relay container talks to the React component and how the Relay container data gets accumulated into one declarative top-level request.\r\n\r\nJust like how we bind callback functions to vdom in the render function, what if we did the same for declarative data fetching?\r\n\r\n```js\r\nfetch = (state, props) => {\r\n  return {\r\n    query: someGraphQLQuery,\r\n    onData: (data) => this.setState({data}),\r\n    onError: (error) => this.setState({error})\r\n  }\r\n}\r\n```\r\n\r\n`fetch` is run everytime render runs and is diffed just like the vdom is diffed. If some request disappears, then its cleaned up automatically. If something is already fetched, then it doesnt re-fetch it.\r\n"}}