简体   繁体   中英

React Redux using Hooks

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. 在此处输入图像描述

You don't need to return a function if you don't do anything asynchronous, so you can just change your action creators to return the action object.

export const depositMoney = amount => ({
  type: 'deposit',
  payload: amount,
})

export const withdrawMoney = amount => ({
  type: 'withdraw',
  payload: amount,
})

If you do need to do something asynchronous inside your action creators you can use the redux-thunk middleware

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));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM