Firstly, I am using react within a Laravel project and trying to list packages within Package.js component through an async call using axios through the use of an action creator. Even though I have used redux-thunk middleware, it throws an error 'Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.'. below is my code and you can even access my code in GitHub - [https://github.com/sunethice/Emerald_Tours].
index.js
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { persistStore } from 'redux-persist';
import { PersistGate } from 'redux-persist/lib/integration/react';
import { configureStore } from './store';
import {BrowserRouter as Router, Link, Route, Switch} from 'react-router-dom';
import './css/index.css';
import Customer from './Customer';
import Admin from './Admin';
class Index extends Component {
render() {
return (
<Router>
<Route exact path="/" component={Customer}></Route>
<Route exact path="/admin" component={Admin}></Route>
</Router>
);
}
}
const store = configureStore();
const persistor = persistStore(store);
ReactDOM.render(
<Provider store={store}>
<PersistGate
loading="<div>Loading...</div>"
persistor={persistor}>
<Index/>
</PersistGate>
</Provider>,
document.getElementById('root'));
store.js
import { createStore, combineReducers, applyMiddleware } from 'redux';
import { packages } from './components/reducers';
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
import thunk from 'redux-thunk';
import { composeWithDevTools } from 'redux-devtools-extension';
const reducers = {
packages,
};
const persistConfig = {
key: 'root',
storage,
stateReconciler: autoMergeLevel2,
}
const rootReducer = combineReducers(reducers);
const persistedReducer = persistReducer(persistConfig, rootReducer);
export const configureStore = () =>
createStore(
persistedReducer,
{},
composeWithDevTools(
applyMiddleware(thunk)
)
);
reducers.js
import { LIST_PACKAGES, LIST_PACKAGES_FAILURE } from './actionTypes';
export const packages = (state = [], action) => {
const { type, payload } = action;
switch(type){
case LIST_PACKAGES:
const newList = {
packages: payload
};
return state.concat(newList);
case LIST_PACKAGES_FAILURE:
return state;
default:
return state;
}
}
actions.js
import axios from 'axios';
import { LIST_PACKAGES, LIST_PACKAGES_FAILURE } from './actionTypes';
export function listPackages () {
return (dispatch) => {
axios.get('/api/packages')
.then((res) =>{
dispatch({type: LIST_PACKAGES ,payload:res.data});
})
.catch((error)=> {
dispatch({type: LIST_PACKAGES_FAILURE, payload: error});
})
}
}
Package.js
import React,{ Component, useState } from "react";
import { connect } from 'react-redux';
import { listPackages } from '../actions';
import pkg1 from '../../img/tour-package1.jpg';
class Package extends Component {
componentDidMount(){
this.props.fetchData();
}
render()
{
return (
<div>
<div className="container mt-5">
<div className="row">
<div className="col-12">
<div className="h3 text-center">
Tour Packages
</div>
<p>
Lorem ipsum dolor sit amet, curabitur nec
lacus pellentesque ut facilisis, lacus iaculis
turpis interdum pede, sapien quis amet vitae,
erat parturient, turpis congue sit. Hac nulla
phasellus ornare. Volutpat risus ipsum nulla
ducimus erat. Scelerisque eu imperdiet wisi
wisi, sit libero sed ipsum sodales phasellus,
odio vel ac non ac, sodales viverra, metus
volutpat quis rutrum diam ac integer. Posuere
nullam eu vestibulum non nonummy. Metus purus
ac malesuada vitae ut qui, sed rhoncus
nonummy, massa ac urna risus, faucibus aliquam
malesuada fusce gravida urna.
</p>
</div>
</div>
<div className="row">
<div className="col-md-12 d-flex justify-content-center mb-5">
<div className="btn-group">
<button
type="button"
className="btn btn-outline-secondary"
data-rel="0"
>
Sri Lanka
</button>
<button
type="button"
className="btn btn-outline-secondary"
data-rel="1"
>
Maldives
</button>
</div>
</div>
</div>
<div className="row">
<div className="col-md-4">
<div className="travel-place">
<div className="work-image">
<img
src={pkg1}
className="img-fluid person"
alt="destination"
/>
<div className="overlay">
<div className="overlay_shape">
<a href="#" className="over-btn">
10 photos
</a>
<a
href="tourpackage.html"
className="view-all"
>
View All Places
<i className="fas fa-long-arrow-alt-right"></i>
</a>
</div>
</div>
</div>
<div className="travel-text">
<h3>Love City, Paris, Italy</h3>
<p>
for 7Days <span>|</span> $ 710.00
</p>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
const mapStateToProps = (state) => ({
packages : state.packages
});
const mapDispatchToProps = (dispatch) => ({
fetchData: () => dispatch(listPackages())
});
export default connect(mapStateToProps, mapDispatchToProps )(Package);
Much appreciate it if you can let me know where I am doing wrong.