I'm trying to create my first react redux using Hooks.
I have a state folder inside my src folder. Inside my state folder I have another folder called reducer and a accountReducer.js file accountReducer.js:
const reducer = (state = 0, action) => {
switch(action.type) {
case "deposit":
return state + action.payload;
case "withdraw":
return state - action.payload;
default:
return state;
}
}
export default reducer;
Also, I have a index.js to combine and export my reducers
import { combineReducers } from "redux";
import AccountReducer from './accountReducer';
const reducers = combineReducers({
account: AccountReducer
});
export default reducers;
In the state folder, I have my store.js
import { createStore } from "redux";
import reducers from './reducers/index';
export const store = createStore(
reducers,
{}
);
I also have an action-creator folder with an index.js file for my actions
export const depositMoney = (amount) => {
return (dispatch) => {
dispatch({
type: "deposit",
payload: amount
});
}
}
export const withdrawMoney = (amount) => {
return (dispatch) => {
dispatch({
type: "withdraw",
payload: amount
});
}
}
Also, in the state folder I have a index.js to export my actionCreators
export * as actionCreators from "./action-creators/index";
In the main index.js file I create a Provider for my store
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from "react-redux";
import { store } from './state/store';
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
Finally, in the App.js I test my redux
import { useSelector, useDispatch } from "react-redux";
import { bindActionCreators } from "redux";
import { actionCreators } from './state/index';
function App() {
const account = useSelector((state) => state.account);
const dispatch = useDispatch();
const { depositMoney, withdrawMoney } = bindActionCreators(actionCreators, dispatch);
return (
<div className="App">
<h1>{account}</h1>
<button onClick={() => depositMoney(500)}>Deposit</button>
<button onClick={() => withdrawMoney(250)}>Withdraw</button>
</div>
);
}
export default App;
When I click on Deposit or Withdraw it returns:
Error: Actions must be plain objects. Instead, the actual type was: 'function'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions.
What am I missing in my code?
Please any advice in my folder structure would be appreciate as well.
Just like the error message suggets, you need to add redux-thunk
in order to be able to use dispatch with functions. Read about it here.
According to the first example, change the code in store.js
to:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducers from './reducers/index';
export const store = createStore(reducers, applyMiddleware(thunk));