Adding array item at specific index - React Redux

Viewed 313

Reducer:

const initState = ['item 1', 'item 2', 'item 3', 'item 4'];

const { text, afterIndex } = action;
switch (action.type) {
  case ADD_NOTE:
    return [
      ...state.slice(0, afterIndex + 1),
      text,
      ...state.slice(afterIndex + 1)
    ];
  default:
    return state;
}

Component, where we're adding a new items:

const enhance = connect(({ items }) => ({ items }), { addItem });

class ItemsList extends React.Component {
  renderItem = item => <div>{item}</div>;

  renderAddButton = (index = 0) => (
    <button
      data-index={index}
      onClick={this.onAddButtonClick}
    >
      Add item
    </button>
  );

  onAddButtonClick = e => {
    const text = window.prompt('Item text:');
    if (text) {
      this.props.addItem(text, e.target.dataset.index);
    }
  };

  render() {
    if (!this.props.items.length) {
      return this.renderAddButton();
    }
    return (
      <ul>
        {this.props.items.map((item, index) => {
          return (
            <li key={index}>
              {this.renderItem(item)}
              {this.renderAddButton(index)}
            </li>
          );
        })}
      </ul>
    );
  }
}

There's 4 items in initial state, i render them through map() in a component, then below each item there's a button to add item after actual item, however only the first button (that adds items in to array) puts an item at correct order.

If i click "add button" on the 2nd, 3rd, 4th item, it adds a new item in array at the end, not after the clicked item.

Visual representation of my case:

1) If i click on the first "Add item" button, then my array would be: ['Item 1', 'my freshly added item', 'Item 2', 'Item 3', 'Item 4']

2) If i click on the second, third, fourth "Add item" button, then my array would be: ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'my freshly added item'], items added to the end of an array, thought it should be after second, third and fourth items.

1 Answers

Turns out, it was dataset attribute, that gave me an index as string, thus in a reducer it was called as '1' + 1.

Solution:

const index = parseInt(afterindex, 10);
Related