简体   繁体   中英

Handling async actions in Redux without any middleware

I am experimenting with async actions, and trying to handle async actions without using any middleware. Here is the code:

import React, { Component } from 'react';
import { render } from 'react-dom';
import { createStore, combineReducers } from 'redux';
import { connect, Provider } from 'react-redux';
import './style.css';

const countReducer = (state = { count: 0}, action) => {
  switch (action.type) {
    case 'INC': return { count: state.count + 1 };
    case 'DEC': return { count: state.count - 1 };
    default: return state;
  }
}

const reducers = combineReducers({
  counter: countReducer,
})

const actions = {
  inc: (async () => {
  return await new Promise(resolve => {
    setTimeout(() => {
      resolve({ type: 'INC' });
    }, 200)}
  );
})(),
  dec: () => ({ type: 'DEC' }),
};

const store = createStore(reducers);

class App extends Component {
  render() {
    console.log(this.props, actions);
    return (
      <div>
        <button onClick={this.props.inc}>Increment</button>
        <button onClick={this.props.dec}>Decrement</button>
        <div>Value: {this.props.count}</div>
      </div>
    );
  }
}

const mapStateToProps = ({ counter }) => {
  return { count: counter.count };
}

const AppContainer = connect(mapStateToProps, actions)(App);

render(
  <Provider store={store}>
    <AppContainer />
  </Provider>,
  document.getElementById('root')
);

You can run above code Here . This does not work as expected. Clicking on 'Decrement' decreases value by 1, but clicking on 'Increment' doesn't do anything. What's wrong in above code and how can I fix it? Is it even possible to handle async actions without using any middleware like redux-thunk?

https://reactjs.org/docs/faq-state.html , tells us that calls to setState are asynchronous and that we must not rely on this.state to reflect the new value immediately after calling setState. Which is kind of forcing you to use the setTimeout . Without using Redux you can find a solution to that problem in the link i've provided. But in your case when you are using redux, you'll find in https://github.com/reduxjs/redux-thunk#why-do-i-need-this :

Thunks are the recommended middleware for basic Redux side effects logic, including complex synchronous logic that needs access to the store, and simple async logic like AJAX requests.

This is an example for a counter https://github.com/reduxjs/redux/tree/master/examples/counter , but you are eventually going to deal with calls to API and other async requests, so I personnally suggest you use thunk because it gives you a better solution, more optimized, faster, and cleaner, since it has been made for situations similar to yours, so no need for you to look for your own workaround. I hope this is helpful.

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