{
    "componentChunkName": "component---src-templates-article-page-template-js",
    "path": "/ftw/ftw-redux/",
    "result": {"data":{"markdownRemark":{"frontmatter":{"title":"How the Redux setup works in FTW","slug":"ftw-redux","updated":"2019-01-29T00:00:00.000Z","category":"ftw-data-flow","ingress":"This article explains how the Redux setup works in Flex Template for Web (FTW).","skills":null},"htmlAst":{"type":"root","children":[{"type":"element","tagName":"h2","properties":{"id":"what-is-redux","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#what-is-redux","ariaLabel":"what is redux permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"What is Redux"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"FTW is JavaScript single-page application (SPA). This means that the app\nneeds to be able to render several different layouts (pages) depending\non user interaction. State management is essential for this process. FTW\nneeds to know if a user has been authenticated, if it has received\nrelevant data for the current page, and so on."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"We use "},{"type":"element","tagName":"a","properties":{"href":"https://redux.js.org/introduction/getting-started","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"Redux"}]},{"type":"text","value":" for\nstate management on the application level. You should read more about\nRedux before you start modifying queries to Flex API or creating new\nPage level elements (unless you are modifying\n"},{"type":"element","tagName":"a","properties":{"href":"/docs/legacy/ftw/how-to-add-static-pages-in-ftw/"},"children":[{"type":"text","value":"a static page"}]},{"type":"text","value":")."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In the following subtopics, we assume that you know the\n"},{"type":"element","tagName":"a","properties":{"href":"https://redux.js.org/basics/basic-tutorial","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"basics of Redux"}]},{"type":"text","value":" already."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"containers-pages--topbarcontainer","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#containers-pages--topbarcontainer","ariaLabel":"containers pages  topbarcontainer permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Containers: Pages + TopbarContainer"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"We have set up FTW so that pages are aware of Redux state store, but\nother components and forms are purely\n"},{"type":"element","tagName":"a","properties":{"href":"https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"presentational components"}]},{"type":"text","value":".\nThis makes it easier to customize UI components - you don't need to be\naware of the complexity related to Redux setup when you just want to\ntouch the behavior of some visual component. In those cases, you can\njust head to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"src/components/"}]},{"type":"text","value":" directory and you can see from there what\nprops are available for each component when they are rendered.\n(FTW-daily and FTW-hourly use also "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"src/forms/"}]},{"type":"text","value":" directory.)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Naturally, there is a need for higher level components which fetch new\ndata and define what props are passed down to presentational components.\nIn Redux terminology, those components are called "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"Containers"}]},{"type":"text","value":". FTW has\ndefined all the containers inside a directory called "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"src/containers/"}]},{"type":"text","value":".\nIt contains all the pages and a special container for top bar\n(TopbarContainer) since that is a very complex component and it is\nshared with almost every page. You can read more about differences\nbetween presentational and container components from an\n"},{"type":"element","tagName":"a","properties":{"href":"https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"article written by Dan Abramov"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The actual container setup of a page level component can be found from\nthe bottom of the component file. For example,\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"src/containers/TransactionPage/TransactionPage.js"}]},{"type":"text","value":" connects itself to\nRedux store with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mapStateToProps"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"mapDispatchToProps"}]},{"type":"text","value":" functions:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" TransactionPage "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"compose"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"connect"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"mapStateToProps"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" mapDispatchToProps"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  injectIntl\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"TransactionPageComponent"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"duck-files","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#duck-files","ariaLabel":"duck files permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Duck files"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Inside "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"src/containers/<ComponentName>"}]},{"type":"text","value":" directory, we have also a\nspecial "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"<ComponentName>.duck.js"}]},{"type":"text","value":" file. These files wrap all the other\npage-specific Redux concepts into a single file. Instead of writing\naction types, action creators and reducers in separate files (and spread\nthem around our directory structure), FTW tries to keep pages\nencapsulated. Page specific actions, store updates, and data fetches\nhappen inside their respective directory - just look for a file which\nname follows a pattern: "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"<ComponentName>.duck.js"}]},{"type":"text","value":". This pattern is just\na simple concept of adding related things into a single file. Read more\nfrom\n"},{"type":"element","tagName":"a","properties":{"href":"https://github.com/erikras/ducks-modular-redux","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"author's repository"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"global-reducers","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#global-reducers","ariaLabel":"global reducers permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Global reducers"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Some reducers are needed in several pages. These global reducers we have\ndefined inside "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"src/ducks/"}]},{"type":"text","value":" directory with their respective "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"*.duck.js"}]},{"type":"text","value":"\nfiles. Most important global duck files are "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"user.duck.js"}]},{"type":"text","value":" and\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"marketplaceData.duck.js"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"setting-up-redux","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#setting-up-redux","ariaLabel":"setting up redux permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Setting up Redux"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Container specific reducers are gathered and exported inside\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"src/containers/reducers.js"}]},{"type":"text","value":" file and global reducers are exported\nrespectively in a file "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"src/ducks/index.js"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"With those exports, we are able to create appReducer\n("},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"src/reducers.js"}]},{"type":"text","value":"):"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" combineReducers "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'redux'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"*"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"as"}]},{"type":"text","value":" globalReducers "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'./ducks'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"*"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"as"}]},{"type":"text","value":" pageReducers "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'./containers/reducers'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" appReducer "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"combineReducers"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":"globalReducers"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"..."}]},{"type":"text","value":"pageReducers"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"appReducer"}]},{"type":"text","value":" is called by "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"createReducer"}]},{"type":"text","value":" function, which is called\ninside of "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"configureStore"}]},{"type":"text","value":" function (in "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"src/store.js"}]},{"type":"text","value":")."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This setup creates a store structure that separates container specific\nstate as well as global data by their reducer names. Together with Ducks\nmodule naming schema, this means that:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"the state of the "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"ListingPage"}]},{"type":"text","value":" can be found from "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"state.ListingPage"}]},{"type":"text","value":"\nand"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"the state of the global "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"user"}]},{"type":"text","value":" object can be found from "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"state.user"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"advanced-redux-concepts-thunks","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#advanced-redux-concepts-thunks","ariaLabel":"advanced redux concepts thunks permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Advanced Redux concepts: thunks"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"One essential part of state management in FTW, is filling the Redux\nstore with data fetched from the Flex API. This is done with\n"},{"type":"element","tagName":"a","properties":{"href":"https://redux.js.org/advanced/async-actions#async-action-creators","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"Redux Thunks"}]},{"type":"text","value":",\nwhich is a Redux middleware to create asynchronous action creators."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"As with every other Redux store actions, we have defined Thunks inside\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"*.duck.js"}]},{"type":"text","value":" file. For example, fetching listing reviews can be done with\na following thunk function:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"export"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function-variable","function"]},"children":[{"type":"text","value":"fetchReviews"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"listingId"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"dispatch"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" getState"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" sdk"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// Make store aware of a request to fetch reviews"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"dispatch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"fetchReviewsRequest"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// Fetch reviews using Flex SDK"}]},{"type":"text","value":"\n  "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" sdk"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"reviews\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"query"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      listingId"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"state"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'public'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"include"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'author'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'author.profileImage'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","string-property","property"]},"children":[{"type":"text","value":"'fields.image'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'variants.square-small'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"then"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"response"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" reviews "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"denormalisedResponseEntities"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"response"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// If fetch succeeds, make store aware of fetched data"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"dispatch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetchReviewsSuccess"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"reviews"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"catch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"e"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// If fetch throws an error, save the error to the store (so that UI can react to it)"}]},{"type":"text","value":"\n      "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"dispatch"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetchReviewsError"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"storableError"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"e"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"blockquote","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Note: "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"sdk"}]},{"type":"text","value":" parameter is also provided by Redux Thunk. We pass it to\nmiddleware in store.js: "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"thunk.withExtraArgument(sdk)"}]}]},{"type":"text","value":"\n"}]}],"data":{"quirksMode":false}},"headings":[{"value":"What is Redux","depth":2},{"value":"Containers: Pages + TopbarContainer","depth":2},{"value":"Duck files","depth":2},{"value":"Global reducers","depth":3},{"value":"Setting up Redux","depth":2},{"value":"Advanced Redux concepts: thunks","depth":2}]}},"pageContext":{"slug":"ftw-redux","category":"ftw-data-flow"}},
    "staticQueryHashes": ["3794076007","439097193","717698143"]}