1
import React, { Component } from 'react';
import { Button } from 'antd';
import { Menu, Dropdown, Icon } from 'antd';
import { Input } from 'antd';
import { List } from 'antd';

class TodoList extends Component {
    state = {
        input: '',
        list: ['todo1', 'todo2']
    }

    render() {
        return (
            <div>
                <Input
                    onChange={this.handleInputChange}
                    value={this.state.input}
                />
                <Button
                    type="primary"
                    onClick={this.handleBtnClick}
                >
                    click me
                </Button>
                <ul>
                    {
                        this.state.list.map((item, index)=> {
                            return (
                                <li key={index}
                                    onClick={this.handleItemDelete}
                                >
                                    {item}
                                </li>
                            )
                        })
                    }
                </ul>
            </div>
        );
    }

    handleInputChange = (e)=>{
        this.setState({
            input: e.target.value
        })
    }

    handleBtnClick = ()=>{
        this.setState({
            list: [...this.state.list, this.state.input],
            input: ''
        })
    }

    handleItemDelete = (index)=>{
        const list = [...this.state.list]; // copy
        list.splice(index, 1); // start from index, delete one element 
        this.setState({
            list: list
        })
    }
}

export default TodoList;

I am a beginner with React. I am writing a TodoList. I already know that function need to bind in the component, so I use ES6 arrow function to do the same thing.

handleItemDelete has bind by using ES6 arrow function, however, the input index is not correct, sometimes it is not the correct index that it should be. I have no idea where goes wrong.

e.g.

todo1

todo2

todo3

If click todo3, todo1 disappear.

Tianbo
  • 67
  • 2
  • 11

4 Answers4

1

You aren't passing index to handleItemDelete function when it is being called. The way you have used it, you would get event as the argument. In order to get the index, you could use it from event which should be a preferred method like

      <ul>
                {
                    this.state.list.map((item, index)=> {
                        return (
                            <li key={index}
                                id={index}
                                onClick={this.handleItemDelete}
                            >
                                {item}
                            </li>
                        )
                    })
                }
            </ul>



   handleItemDelete = (event)=>{
        const index = event.target.id;
        const list = [...this.state.list]; // copy
        list.splice(index, 1); // start from index, delete one element 
        this.setState({
            list: list
        })
    }

However you can achieve the same by using an arrow function and passing it as the argument like

<li key={index}
     onClick={() => this.handleItemDelete(index)}
>
      {item}
</li>

Please also have a look at How to avoid binding inside render method

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
0

Try to pass index manually like this:

onClick={() => this.handleItemDelete(index)}
Azamat Zorkanov
  • 779
  • 1
  • 4
  • 9
0

An arrow function does not have its own this, but it has the this value of the enclosing execution context. Arrow Functions lexically bind their context so this actually refers to the originating context. That’s called Lexical Scoping if you’re into naming things. Basically, it saves us from doing .bind(this) in our code. Note that this is an experimental feature in JS, which means it’s not yet accepted into ECMAScript standard

So, you can use it like below:

onClick={() => this.handleItemToDelete(index)}

In your render method you do something like:

class TodoList extends Component {
  render() {
    return (
        <li key={index}
           onClick={ () => this.handleItemToDelete(index) }
        >
           {item}
        </li>
    );
  }
}

Read more about arrow functions in this article:

Arrow_functions in details

Mselmi Ali
  • 1,139
  • 2
  • 18
  • 28
0

if you want to call your function like

onClick={this.handleItemDelete(i)}

then write your function like this

handleItemDelete = i => e => {
    value = e.target.value;
};
Vampire
  • 109
  • 1
  • 4