Veljko Simic
Veljko Simic

Reputation: 71

Remove Element when change redux state

I have problem with updating component when remove element from redux state.

my component:

const mapStateToProps = state => ({
  products: state.shoppingBasket.list,
});

const ShoppingBasket = React.createClass({
  propTypes: {
    removeProduct: React.PropTypes.func.isRequired,
    products: React.PropTypes.array,
    open: React.PropTypes.func.isRequired,
  },
  removeFromBasket(index, name) {
    this.props.removeProduct(index);
  },
  render() {
    return (
      <div>
        {this.props.products.map((product, index) => (
              <div key={index}>
                product.name
                <button onClick={() => this.RemoveFromBasket(index)}
              </div>
            );
          )}
      </div>
    );
  },
});

export default connect(mapStateToProps, actions)(ShoppingBasket);

my reducer:

export default function shoppingBasket(
  state = {
    list: [],
  },
  action
) {
  let tmp = [];
  switch (action.type) {
    case SHOPPING_BASKET_ADD:
      return { list: [...state.list, action.payload.product] };
    case SHOPPING_BASKET_REMOVE:
      tmp = state.list;
      tmp.splice(action.payload.index, 1);
      return { list: tmp };
    default:
      return state;
  }
}

When insert element in redux state my component successfuly update, but when i click on button and call removeFromBasket element was remove from redux state but commponent shouldn't update.

Upvotes: 1

Views: 1038

Answers (1)

Bartek Fryzowicz
Bartek Fryzowicz

Reputation: 6684

splice doesn't return new array but only mutates array on which it's called so refernce to list property doesn't change. In Redux you must always return new state object (never mutate state) otherwise your component will not updated because internally it performs shallow comparision of current and next properties so if references hasn't changed it considers them equal and prevents component re-render. You can remove item fron an array in a Redux way like this:

   case SHOPPING_BASKET_REMOVE:
      return { list: [
       ...state.list.slice(0, action.payload.index),
       ...state.list.slice(action.payload.index + 1)
      ]
   }

Upvotes: 3

Related Questions