0
votes

I'm trying to use Redux, Redux-Thunk in my app. I did it before and it worked but here it keeps showing Error: Expected the reducer to be a function

scr/App.js;

import React, { Component } from 'react';
import { Router } from 'react-router-dom';
import { createBrowserHistory } from 'history';
import { Chart } from 'react-chartjs-2';
import { ThemeProvider } from '@material-ui/styles';
import { chartjs } from './helpers';
import theme from './theme';
import 'react-perfect-scrollbar/dist/css/styles.css';
import './assets/scss/index.scss';
import Routes from './Routes';
import { Provider } from 'react-redux';

// redux
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly';
import * as actionTypes from './store/actions/actionTypes';
import rootReducer from './store/reducers/rootReducer';

const browserHistory = createBrowserHistory();

Chart.helpers.extend(Chart.elements.Rectangle.prototype, {
  draw: chartjs.draw
});

const store = createStore(
  rootReducer,
  compose(applyMiddleware(thunk), composeWithDevTools)
);

export default class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <ThemeProvider theme={theme}>
          <Router history={browserHistory}>
            <Routes />
          </Router>
        </ThemeProvider>
      </Provider>
    );
  }
}

when I tried to log rootReducer it logged an empty line for the initial load then the app breaks then it logs the rootReducer

src/store/rootReducer.js

import { combineReducers } from 'redux';
import searchReducer from './searchReducer';

const rootReducer = combineReducers({
  searchReducer: searchReducer
});

export default rootReducer;

src/store/reducers/searchReducer.js

import * as actionTypes from '../actions/actionTypes';

const initialState = {
  loading: false,
  result: [],
  error: ''
};

const searchReducer = (state = initialState, action) => {
  switch (action.type) {
    case actionTypes.SEARCH_TRIGGER:
      return {
        ...state,
        loading: true,
        result: [],
        error: ''
      };
    case actionTypes.SEARCH_ERROR:
      return {
        ...state,
        loading: false,
        result: [],
        error: action.error
      };
    case actionTypes.SEARCH_SUCCESS:
      return {
        ...state,
        loading: false,
        error: '',
        result: action.result
      };
    default:
      return state;
  }
};

export default searchReducer;

src/store/actions/actionTypes.js

// create campaign actions
export const UPDATE_STEPPER_STATE = 'UPDATE_STEPPER_STATE';
export const SEARCH_TRIGGER = 'SEARCH_TRIGGER';
export const SEARCH_SUCCESS = 'SEARCH_SUCCESS';
export const SEARCH_ERROR = 'SEARCH_ERROR';

src/store/actions/stepperActions.js

import * as actionTypes from './actionTypes';

export const updateStepperState = data => {
  return {
    action: actionTypes.UPDATE_STEPPER_STATE,
    data
  };
};

exported in index.js inside the same directory

export { updateStepperState } from './stepperActions';

packages

"react-redux": "^7.1.3",
"redux": "^4.0.4",
"redux-devtools-extension": "^2.13.8",
"redux-thunk": "^2.3.0",
"thunk": "0.0.1",
2

2 Answers

1
votes

It looks like your path to searchReducer is incorrect.

Change this:

import searchReducer from './searchReducer';

to this:

import searchReducer from './reducers/searchReducer';

in your rootReducer.js file.

It's giving you the error Expected the reducer to be a function because searchReducer is returning undefined.

1
votes

hey try creating store like this

const store = createStore(
  rootReducer,
  composeWithDevTools(applyMiddleware(thunk))
);

i think you can not use multiple store enhancers together,you either choose compose or composeWIthDevTools,and create store based on environment like for development use composeWithDevTools and for production use compose