Search code examples
reactjsreduxreact-reduxredux-thunk

Try to connect Action with Reducer but get Error: Uncaught (in promise) TypeError: dispatch is not a function


Friends, I have a problem with the connection between Action and Reducer when trying to send data that come back from the API I get dispatch, not a function and when trying to console.log(action.type) I get @@redux/INITw.y.u.w.s.a are any help, and thanks very much

Store

import { createStore, applyMiddleware , compose } from 'redux'
import reduxThunk from 'redux-thunk';
import combineReducers from './Reducers/index';

const enhancer = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
let store = createStore(combineReducers,enhancer(applyMiddleware(reduxThunk)))

export default store;

Action

import { READ_USER_DATA } from './../Types';

export const fetchUser = () => {
    return (dispatch) => {
        fetch(`https://jsonplaceholder.typicode.com/users`).then(response => response.json()).then(data => {
            dispatch({
                type: READ_USER_DATA,
                data: data
            })
        })
    }
}

Reducer

import { READ_USER_DATA } from './../Types';

const userReducer = (state = {}, action) => {
    switch (action.type) {
        case READ_USER_DATA:
            return { ...state,userInfo: action.data  }
        default:
            return state;
    }
}

export default userReducer;

combine Reducers

import { combineReducers } from "redux";
import userReducer from './UserReducer';

export default combineReducers({
    user: userReducer,
})

connect - Code in component-

export default connect((state) => {
    console.log(state)
    return {
        userInfo: state.user.userInfo
    }
},{ fetchUser })(Home)

Solution

  • I am using the useEffect useEffect(() => ( fetchUser() ), [])

    For one, you have to use {}, not () in your useEffect. Also, you need to call props.fetchUser, not fetchUser directly when you are using the legacy connect function. You should generally not use connect in function components, it is a legacy api to support legacy class components.

    So it would look like

    useEffect(() => { props.fetchUser() }, [])
    

    But it should even be

    const userInfo = useSelector(state => state.user.userInfo)
    const dispatch = useDispatch()
    useEffect(() => { dispatch(fetchUser()) }, [])
    

    without using connect at all.