0

I am trying to implement the following example in my project: https://github.com/reactjs/redux/tree/master/examples/async

But I keep running into the error: dispatch is not function when executing the dispatch function from my actions class.

It seems as if Dispatcher is not getting passed down to my actions but I followed the flow in the example:

actions/index.js file:

    export const REQUEST_LOCAL_POSTS = 'REQUEST_LOCAL_POSTS';
export const RECEIVE_LOCAL_POSTS = 'RECEIVE_LOCAL_POSTS';
export const REQUEST_CURRENT_LOCATION = 'REQUEST_CURRENT_LOCATION';
export const RECEIVE_CURRENT_LOCATION = 'RECEIVE_CURRENT_LOCATION';


export const requestCurrentLocation = () => ({
    type: REQUEST_CURRENT_LOCATION
})

export const receiveCurrentLocation = currentLocation => ({
    type: RECEIVE_CURRENT_LOCATION,
    currentLocation,
    receivedCurrentLocationAt: Date.now()
})

export const requestLocalPosts = () => ({
    type: REQUEST_LOCAL_POSTS
})

export const receiveLocalPosts = json => ({
    type: RECEIVE_LOCAL_POSTS,
    posts: json,
    receivedAt: Date.now() 
})

export const fetchLocalPosts = dispatch => {
    dispatch(requestCurrentLocation())
    navigator.geolocation.getCurrentPosition(
      (position) => {
         dispatch(requestLocalPosts()) // getting dispatch is not a function here
        return fetch(`http://192.168.1.3:9000/posts?lng=${position.coords.longitude}&lat=${position.coords.latitude}&radius=1000`)
    .then(response => response.json())
    .then(json => dispatch(receiveLocalPosts(json)))

      },
      (error) => this.setState({ error: error.message }),
      { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
    )

home.js (component):

import React, { Component } from 'react';
import {Text, View, ActivityIndicator, FlatList, Image, TouchableHighlight} from 'react-native';
import styles from './styles';
import MapView from 'react-native-maps';
import images from '../../config/images';
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { fetchLocalPosts } from '../../actions'


 class Home extends Component {

    static navigationOptions = ({ navigation }) => {
//const {dispatch , state, setParams} = navigation;

  return {
    title:<Text style={styles.title}>Localized</Text>,
    headerStyle: {backgroundColor: '#2c6da4'},
    headerRight: (
      <TouchableHighlight onPress={() => navigation.dispatch({ type: 'MAP_EXPLORE' })}>
  <Image
        source={images.icons.map}
      />
    </TouchableHighlight>

    ),
  };
};

static propTypes = {
    posts: PropTypes.array.isRequired,
    isFetching: PropTypes.bool.isRequired,
    lastUpdated: PropTypes.number,
    dispatch: PropTypes.func.isRequired
  }




    componentDidMount() {
        console.log(this.props)
        const { dispatch } = this.props
        dispatch(fetchLocalPosts()) // calling action from here
    }



    render() {


        return (

            <View style={styles.container}>

                 // i know posts isnt accessed here yet, still trying 
                 to get past error
                <FlatList
                    data={this.state.data}
                    refreshing={this.state.refreshing}
                    showsVerticalScrollIndicator={false}
                    ListHeaderComponent={this.renderHeader}
                    onRefresh={this._onRefresh.bind(this)}

                    renderItem={({item}) => <View><FlatList
                        data={item.posts}
                        horizontal={true}
                        snapToAlignment='center'
                        showsHorizontalScrollIndicator={false}
                        renderItem={({item}) => <Text style={styles.item}>{item.title}{"\n"}{item.snippet}</Text>}/>
                        <Text style={styles.subItem}>{item.Name}{"\n"}{item.Address}</Text>
                    </View>}

                />

            </View>

        );
    }


}

const mapStateToProps = state => {
  const { postsByBusiness } = state
  const {
    isFetching,
    lastUpdated,
    items: posts
  } = postsByBusiness || {
    isFetching: true,
    items: []
  }

  return {
    posts,
    isFetching,
    lastUpdated
  }
}

export default connect(mapStateToProps)(Home)

reducer/index.js:

import { combineReducers } from 'redux';
import { NavigationActions } from 'react-navigation';

import { AppNavigator } from '../navigators/AppNavigator';

import { RECEIVE_LOCAL_POSTS, REQUEST_LOCAL_POSTS } from '../actions';


const initialNavState=AppNavigator.router.getStateForAction(NavigationActions.reset({
    index: 0,
    actions: [
      NavigationActions.navigate({
        routeName: 'Home',
      }),
    ],
}));



const MAP_EXPLORE = 'MAP_EXPLORE';
const LIST_EXPLORE = 'LIST_EXPLORE';


function nav(state = initialNavState, action) {
    let nextState;
    switch(action.type) {
        case MAP_EXPLORE:
        nextState = AppNavigator.router.getStateForAction(
            NavigationActions.navigate({ routeName: 'Map'}),
            state
            );
        break;
        case LIST_EXPLORE:
        nextState = AppNavigator.router.getStateForAction(
            NavigationActions.navigate({ routeName: 'List'}),
            state
            );
        break;
        default:
            nextState = AppNavigator.router.getStateForAction(action, state);
            break;
    }
    return nextState || state;

}


function postsByBusiness(state = { }, action) {
    switch(action.type) {
        case RECEIVE_LOCAL_POSTS:
        return {
            ...state,
            isFetching: false,
        didInvalidate: false,
        items: action.posts,
        lastUpdated: action.receivedAts
        }
        default:
        return state
    }
}




const AppReducer = combineReducers({
  nav,
  postsByBusiness

});

export default AppReducer;

1 Answer 1

1

fetchLocalPosts should be returning a function that takes dispatch as an argument. Changing it to the following should fix it.

export const fetchLocalPosts = () => dispatch => {
  ...

It's another way of doing this:

export const fetchLocalPosts = () => {
    return function (dispatch) {
      ...
Sign up to request clarification or add additional context in comments.

1 Comment

thanks, this really helped me! didn't realize i should be returning a function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.