Redux async dispatch issue

by nickkell

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.0/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.5.2/redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.4.5/react-redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.13.0/polyfill.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.2/lodash.js"></script>
<div id="container">
  <!-- Yield to React -->
</div>

Babel + JSX

const itemReducer = (currentState, action) => {
	currentState = currentState || {
  	items: [
    	{ id: 1, text: 'one', removed: false },
      { id: 2, text: 'two', removed: false }
    ]
  }; // Initial State
  
  switch (action.type) {
  	case 'MARK_REMOVED':
    	return {
      	items: currentState.items.map(function(item) {
        	return item.id !== action.id ? 
          	item :
          	{ 
            	...item,
              removed: true
            };
        })
      };
    case 'REMOVE':
      return {
        items: currentState.items.filter(({id}) => id !== action.id)
      };
    default:
    	return currentState; // Always return the state
  }
};

// Create Store
const itemStore = Redux.createStore(itemReducer);

const Item = React.createClass({
	onRemove() {
  	this.props.onRemove(this.props.id);
  },
  
  render: function () {
  	return (
    	<tr>
    	  <td>{this.props.id}</td>
        <td>{this.props.text}</td>
        <td><button onClick={this.onRemove}>Remove</button></td>
    	</tr>
    );
  }
});

const mapStateToProps = (state, { id }) => {
	var {text} = state.items.filter((x) => x.id === id)[0];
	return {
  	id: id,
    text: text
  };
};

const mapDispatchToProps = (dispatch) => {
	return {
  	onRemove(id) {
    	setTimeout(() => {
      	dispatch({
        	type: 'MARK_REMOVED',
          id
        });	
        dispatch({
        	type: 'REMOVE',
          id
        });	
     }, 0);
    }
  };
 };
 
 // Container components (Pass props into presentational component)
 const ItemConnected = ReactRedux.connect(mapStateToProps, mapDispatchToProps)(Item);
 
 // Top-Level Component
 const App = React.createClass({
 	render: function () {
  	return (
    	<table>
        <thead>
          <tr></tr>
        </thead>
        <tbody>
          { this.props.items.map((item) => 
          	<ItemConnected id={item.id} />) }
        </tbody>
      </table>
     );
  }
 });
 
const app_mapStateToProps = ({ items }) => ({
	items:...