3
votes

I have these files and somehow when I dispatch something, it always returns the default case of the reducer.

This is the first time I'm using redux/thunk, and I'm following this tutorial: https://www.youtube.com/watch?v=nrg7zhgJd4w and when he's doing it, it works..

Please have a look at my code :

react component:

import React, { Component } from 'react';
import './App.css';
import Request from 'request';
import { connect } from 'react-redux'

import * as OperationsActions from './actions/operationsReducerActions'

//import { Content, FilterSelect, ListItem, Searchbar, Sidebar} from './components/index.js'

function mapStateToProps(state){
  return {
    operations : state.operations
  }
}

class App extends Component {
  constructor(props){
    super(props);   
  }
  componentDidMount(){
    this.props.dispatch( OperationsActions.getOperations() );
  }
  render() {
    console.log(this.props)
    return(
      <div>{this.props.operations.operations[0].text}</div>
    )   
  }
}

export default connect(mapStateToProps)(App)

actions files :

import Request from 'request';

export function getOperations(){
        Request('http://localhost:8000/client/REQUEST_OPERATIONS', (error, response, data) => {
            if(!error){
                return {type : 'FETCH_OPERATIONS_SUCCES', payload : data};
            }
            else {
                return {type : 'FETCH_OPERATIONS_REJECTED', payload : error}
            }
    });
}

reducer:

 export default function    reducer(state={
        operations : [{
            text : '',
            reqArgument : '',
            filters : [],
            url : ''
        }],
        fetching : false,
        fetched : false,
        error : null
    }, action) {

        switch(action.type){
            case 'FETCH_OPERATIONS':{
                return {...state, fetching : true }
            }
            case 'FETCH_OPERATIONS_REJECTED':{
                return {...state, fetching : false, error : action.payload}
            }
            case 'FETCH_OPERATIONS_SUCCES':{
                return {...state, fetched : true, fetching : false, operations : action.payload }
            }
            default : {
                return {...state}
            }
        }
    }

and my store:

import { applyMiddleware, createStore } from 'redux'

    import logger from 'redux-logger'
    import thunk from 'redux-thunk'
    import promise from 'redux-promise-middleware'

    import reducer from './reducers'

    const middleware = applyMiddleware(promise, thunk, logger)

    export default createStore(reducer, middleware)
1
What isn't working exactly? Please try and highlight the issue if you can. Is nothing showing up on screen? Did you try logging any values with console.log() ?Christopher Messer
Yes I tried console logging stuff, the problem is that my reducer always keeps giving back the default case/state, or my dispatcher doesn't work properly...Laurens Mäkel

1 Answers

2
votes

Problem

class App extends Component {
  ...
  componentDidMount(){
    this.props.dispatch(OperationsActions.getOperations());
  }
  ...
}

Calling OperationsActions.getOperations() will return undefined – it doesn't explicitly return anything. As a result your reducer will receive undefined as its action argument. The switch will then run its default case.

Solution

Your getOperations action should be converted to a thunk. Here is an example:

function getOperationsThunk() {
   return function (dispatch) {
     Request('http://foo.bar', (err, data) => {
       if (err) { dispatch(errorAction(err)); }
       else { dispatch(successAction(data)); }
     });
   };
}

The errorAction and successAction functions will receive the data from the async request and create the action object to be dispatched.

Further reading