Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redux-thunk dispatch method fires undefined action

Here is the code I'm playing with

import { createStore, applyMiddleware } from 'redux' import thunk from 'redux-thunk' import axios from 'axios'  const initialState = {     user: {},     requesting: false,     err: null }  const reducer = (state = initialState, action) => {     switch (action.type) {         case 'REQ_USER_INIT': return { ...state, requesting: true }         case 'REQ_USER_DATA': return { ...state, requesting: false, user: action.user }         case 'REQ_USER_ERR': return { ...state, requesting: false, err: action.err }     }     return state; }  const logger = (store) => (next) => (action) => {     let previous = JSON.stringify(store.getState())     next(action)     console.log(         'action: ' + JSON.stringify(action) +         '\n\tprevious: ' + previous +         '\n\tcurrent: ' + JSON.stringify(store.getState())     ) }  const store = createStore(reducer, applyMiddleware(logger, thunk))  store.dispatch((dispatch) => {     dispatch({ type: 'REQ_USER_INIT' })      // Fake Online REST API for Testing and Prototyping     // break url to get an error response     let usersEndpoint = 'https://jsonplaceholder.typicode.com/users/1'      axios.get(usersEndpoint)         .then((response) => {             dispatch({                 type: 'REQ_USER_DATA',                 user:  {                     id: response.data.id,                     username: response.data.username,                     email: response.data.email,                 }             })         })         .catch((error) => {             dispatch({                 type: 'REQ_USER_ERR',                 err: error.message             })     }) }) 

I believe it is pretty straightforward, right? I dispatch REQ_USER_INIT and then REQ_USER_DATA once the response is received. I should log two actions, however I get 3. Second action is undefined and I am strugling to figure out what causes it. Is it a bug with redux-thunk or am I doing something wrong?

Here is the output from my console:

action: {"type":"REQ_USER_INIT"} ·previous: {"user":{},"requesting":false,"err":null} ·current: {"user":{},"requesting":true,"err":null} action: undefined ·previous: {"user":{},"requesting":false,"err":null} ·current: {"user":{},"requesting":true,"err":null} action: {"type":"REQ_USER_DATA","user":{"id":1,"username":"Bret","email":"[email protected]"}} ·previous: {"user":{},"requesting":true,"err":null} ·current: {"user":{"id":1,"username":"Bret","email":"[email protected]"},"requesting":false,"err":null} 
like image 800
FullStackForger Avatar asked Sep 01 '16 12:09

FullStackForger


People also ask

How does a thunk have access to dispatch?

Where does this new dispatch argument come from? The short answer is that the redux-thunk middleware has access to the store, and can therefore pass in the store's dispatch and getState when invoking the thunk. The middleware itself is responsible for injecting those dependencies into the thunk.

What is Dispatch in Redux thunk?

Redux Thunk is a middleware that lets you call action creators that return a function instead of an action object. That function receives the store's dispatch method, which is then used to dispatch regular synchronous actions inside the function's body once the asynchronous operations have been completed.

Who is responsible for dispatching the action in Redux?

A Redux app really only has one reducer function: the "root reducer" function that you will pass to createStore later on. That one root reducer function is responsible for handling all of the actions that are dispatched, and calculating what the entire new state result should be every time.

How does Redux thunk fetch data?

There is an issue with how fetchComments method is called inside the <Dashboard> component. Once a React component is connected to a Redux store, the data from the store ( mapStateToProps ) and the functions it can use to dispatch actions to the store ( mapDispatchToProps ) are passed to that component as an object.


1 Answers

The order of middlewares matters. Try making logger last

const store = createStore(reducer, applyMiddleware(thunk, logger)) 
like image 149
Yury Tarabanko Avatar answered Sep 30 '22 07:09

Yury Tarabanko