Dan
Dan

Reputation: 251

How to retrieve state data after async action dispatch with Redux?

I am new to using Redux and Thunk and I need some help it's a very confusing concept to me. I have followed multiple tutorials and videos and managed to get a working async action using the Thunk middleware. I am basically fetching JSON data from my server and updating state accordingly for start, receive and error actions (see code below). The problem I'm having is when I execute the store.dispatch(fetchAllBugData()) method with my Thunk action creator, I can see with the Logger middleware I have that it's working it goes through first the start actions setting fetching: true then once it has the data I can see fetching: false and my bugs array is populated with all my data. Great this works!

However, I can't seem to figure out how to actually access my store's state after that if I do a console.log(store.getState()) after dispatching, it gives me the state before the data was retrieved (aka when fetching: true). Why is this? How can I access the state after my data has been retrieved from the fetch so I can actually do something useful with it in my application?

Below is all my code related to the action, reducer and store. Thanks!

BugDataActions.js

export const fetchAllBugData = () => {

   return (dispatch) => {

      dispatch({type: FETCH_ALL_BUG_DATA_START})

   BugsApi.getBugData(data => {

      dispatch({type: RECEIVE_ALL_BUG_DATA, payload: data})

   }, err => {

      dispatch({type: FETCH_ALL_BUG_DATA_ERROR, payload: err})
   })

  }

}

BugDataReducer.js

const initialState = {
   fetching: false,
   fetched: false,
   bugs: [],
   fetcherr: null,
   noresultserr: null
}

const bugDataReducer = (state = initialState, action) => {

switch(action.type) {

  case "FETCH_ALL_BUG_DATA_START": {
    return {
      ...state,
      fetching: true
    }
    break;
  }

  case "RECEIVE_ALL_BUG_DATA": {
    return {
      ...state,
      fetching: false,
      fetched: true,
      bugs: action.payload
    }
    break;
  }

  case "FETCH_ALL_BUG_DATA_ERROR": {
    return {
      ...state,
      fetching: false,
      fetcherr: action.payload
    }
    break;
  }
}

return state;
}

configureStore.js

import { createStore, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
import loggerMiddleware from 'redux-logger'
import rootReducer from './../reducers/index'

export default function configureStore() {
return applyMiddleware(thunkMiddleware, loggerMiddleware()(createStore)(rootReducer)
}

Index.js

import configureStore from './store/configureStore'
import {fetchAllBugData} from './actions/BugDataActions'
import {fetchBugDataByParams} from './actions/BugDataActions'

const store = configureStore()
console.log(store.dispatch(fetchAllBugData()))

Upvotes: 0

Views: 1810

Answers (1)

Ori Drori
Ori Drori

Reputation: 191976

Dispatching an async action via redux-thunk means that you won't know when the store updates. Subscribe to the store via a callback, and when the store changes, get the new state from the store, and perform whatever action you want to do. Of course, Subscribing to the store is also used to handle synchronous changes.

store.subscribe(() => {
    const state = store.getState();
    // do whatever you want with the new state
});

When you're using react with redux, add react-redux, which will save you the hassle of subscribing to the store in each component that needs to get the updated state.

Upvotes: 0

Related Questions