简体   繁体   中英

Redux - updating store based on async api calls

I have a use case to render page using redux with graphql api calls.

On first component will call default action to fetch data from graphql, and stores in redux state as below

state = { films: {
               totalCount: 6,
               films: [
                        {
                          created: '2014-12-10T14:23:31.880000Z',
                          id: 'ZmlsbXM6MQ==',
                          director: 'George Lucas',
                          title: 'A New Hope'
                        },
                        {
                          created: '2014-12-12T11:26:24.656000Z',
                          id: 'ZmlsbXM6Mg==',
                          director: 'Irvin Kershner',
                          title: 'The Empire Strikes Back'
                        },
                        {
                          created: '2014-12-18T10:39:33.255000Z',
                          id: 'ZmlsbXM6Mw==',
                          director: 'Richard Marquand',
                          title: 'Return of the Jedi'
                        }
                      ]
                 }
         }

and will show UI like below Films demo app UI screenshot

Once placed in individual component (Film), i have to make service call to get film details by id ( this calls will be async to fetch data and has to store in state.

Will get data as below

{ "data": {
"film": {
  "id": "ZmlsbXM6NQ==",
  "title": "Attack of the Clones",
  "created": "2014-12-20T10:57:57.886000Z",
  "director": "George Lucas",
  "releaseDate": "2002-05-16",
  "episodeID": 2,
  "openingCrawl": "There is unrest in the Galactic\r\nSenate. Several thousand solar\r\nsystems have declared their\r\nintentions to leave the Republic.\r\n\r\nSenator Amidala, the former\r\nQueen of Naboo, is returning\r\nto the Galactic Senate to vote\r\non the critical issue of creating\r\nan ARMY OF THE REPUBLIC\r\nto assist the overwhelmed\r\nJedi....",
  "producers": [
    "Rick McCallum"
   ]
  }
}

}

Now i have to update my state like below, so that i can show all film data in individual (Film) component

state = { films: {
           totalCount: 6,
           films: [
                    {
                      "id": "ZmlsbXM6NQ==",
                      "title": "Attack of the Clones",
                      "created": "2014-12-20T10:57:57.886000Z",
                      "director": "George Lucas",
                      "releaseDate": "2002-05-16",
                      "episodeID": 2,
                      "openingCrawl": "There is unrest in the Galactic\r\nSenate. Several thousand solar\r\nsystems have declared their\r\nintentions to leave the Republic.\r\n\r\nSenator Amidala, the former\r\nQueen of Naboo, is returning\r\nto the Galactic Senate to vote\r\non the critical issue of creating\r\nan ARMY OF THE REPUBLIC\r\nto assist the overwhelmed\r\nJedi....",
                      "producers": [
                               "Rick McCallum"
                         ]
                    },
                    {
                      "id": "ZmlsbXM6Mg==",
                      "title": "The Empire Strikes Back",
                      "created": "2014-12-12T11:26:24.656000Z",
                      "director": "Irvin Kershner",
                      "releaseDate": "2002-05-16",
                      "episodeID": 2,
                      "openingCrawl": "There is unrest in the Galactic\r\nSenate. Several thousand solar\r\nsystems have declared their\r\nintentions to leave the Republic.\r\n\r\nSenator Amidala, the former\r\nQueen of Naboo, is returning\r\nto the Galactic Senate to vote\r\non the critical issue of creating\r\nan ARMY OF THE REPUBLIC\r\nto assist the overwhelmed\r\nJedi....",
                      "producers": [
                               "Rick McCallum"
                         ]
                    },
                    {
                      "id": "ZmlsbXM6Mw==",
                      "title": "Return of the Jedi",
                      "created": "2014-12-18T10:39:33.255000Z",
                      "director": "Richard Marquand",
                      "releaseDate": "2002-05-16",
                      "episodeID": 2,
                      "openingCrawl": "There is unrest in the Galactic\r\nSenate. Several thousand solar\r\nsystems have declared their\r\nintentions to leave the Republic.\r\n\r\nSenator Amidala, the former\r\nQueen of Naboo, is returning\r\nto the Galactic Senate to vote\r\non the critical issue of creating\r\nan ARMY OF THE REPUBLIC\r\nto assist the overwhelmed\r\nJedi....",
                      "producers": [
                               "Rick McCallum"
                         ]
                    }
                  ]
             }
     }

When i am trying action to fetch Film by id (async calls using api middleware) in Film component, its calling and trying to update but all actions are looping and not working properly.

Please help me to understand and use redux actions properly.

App Codesandbox link https://codesandbox.io/s/adoring-jang-bf2f8m Verify the console logs, can see actions looping....

Thanks.

Update:: Updated the above app to @redux/toolkit, below is the ref url https://codesandbox.io/s/react-rtk-with-graphql-9bl8q7

You are using a highly outdated style of Redux here that will make you write 4 times the code at no benefit - modern Redux does not have ACTION_TYPE constants, switch..case reducers , hand-written middleware (at least in a case like yours), immutable reducer logic or hand-written action creators - all that since 2019. The tutorial you are following is highly outdated and the problems you are facing right now will not be problems for you if you go with the modern style.

Please do yourself a favor and go follow the official Redux tutorial . It also covers getting data from apis in chapters 5, 7 and 8.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM