4

I'm currently receiving the error TypeError: getState is not a function I'm attempting something similar to the example at http://redux.js.org/docs/advanced/AsyncActions.html

action.js - error occurs here

export const fetchCategoriesIfNeeded = (dispatch, getState) => {
    if(shouldFetchCategories(getState())){
        return dispatch(fetchCategories())
    }
}

App.js

  componentDidMount(){
    this.props.dispatch(fetchCategoriesIfNeeded())
  }

...

const mapStateToProps = (state, props) => {
  return {
    isFetching: state.isFetching,
    categories: state.categories
    }
}

reducer.js

function data (state = initialState, action){
    switch(action.type){
        case RECEIVE_CATEGORIES:
            return {
                ...state,
                isFetching: false,
                categories: action.categories
            }
        case REQUEST_CATEGORIES:
            return {
                ...state,
                isFetching: true
            }
        default:
            return state
    }
    return state
}

omitted some of the code for readability.

I've also tried this and receive TypeError: dispatch is not a function

export function fetchCategoriesIfNeeded(){
    return(dispatch, getState) =>{
        var state = getState()
        if(shouldFetchCategories(state)){
            dispatch(fetchCategories())
        }
    }
}
Grant M
  • 51
  • 2
  • 5
  • 1
    Well, you're not passing anything into fetchCategoriesIfNeeded when you call it, so it makes sense it would flail when it tries to call getState. – Dave Newton Aug 23 '17 at 02:49
  • I'm guessing (we can't see `this.props.dispatch` but the name leads me to believe) that you meant `this.props.dispatch(fetchCategoriesIfNeeded)` –  Aug 23 '17 at 20:03
  • I'm using thunk middleware. I changed my code slightly but now it says dispatch is not a function. – Grant M Aug 24 '17 at 00:42
  • https://stackoverflow.com/questions/35667249/accessing-redux-state-in-an-action-creator – Grant M Aug 24 '17 at 00:43

2 Answers2

5

Change

export const fetchCategoriesIfNeeded = (dispatch, getState) => {

to

export const fetchCategoriesIfNeeded = () => (dispatch, getState) => {

Your action creator needs to return either an action (aka an object with a type key) or function (courtesy of redux-thunk). Your function signature had you passing in two parameters, dispatch and getState while the second function signature takes no parameters but the return function does take dispatch and getState, which are provided by redux-thunk.

You could also write it out to avoid confusion like so

export const fetchCategoriesIfNeeded = () => {
    return (dispatch, getState) => {
       // Do stuff
    }
}

Hope that helps!

KernelSanders
  • 387
  • 3
  • 10
0

It looks like you're doing something weird with how you're calling the dispatch.

You should be using a mapDispatchToProps function as well.

eg. something like this:

const mapDispatchToProps = (dispatch, props) => {
   return {
       onUpdate: dispatch(fetchCategories())
    }
}


const mapStateToProps = (state, props) => {
  return {
    isFetching: state.isFetching,
    categories: state.categories
    }
}

and:

  componentDidMount(){
    this.props.onUpdate(); 
  }
dwjohnston
  • 11,163
  • 32
  • 99
  • 194