用ES6反应绑定问题

时间:2018-08-29 06:54:08

标签: reactjs ecmascript-6

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;

我是React的初学者。 我正在写一个TodoList。 我已经知道该功能需要绑定到组件中,所以我使用ES6箭头功能执行相同的操作。

handleItemDelete通过使用ES6箭头功能进行了绑定,但是输入索引不正确,有时它不是应该正确的索引。我不知道哪里出了问题。

例如

todo1

todo2

todo3

如果单击todo3,则todo1消失。

4 个答案:

答案 0 :(得分:1)

调用索引时,您不会将索引传递给handleItemDelete函数。使用它的方式,您将获得event作为参数。为了获取索引,您可以在事件中使用它,它应该是首选方法,例如

      <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
        })
    }

但是,您可以通过使用箭头函数并将其作为参数传递,例如

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

也请看看How to avoid binding inside render method

答案 1 :(得分:0)

尝试像这样手动传递索引:

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

答案 2 :(得分:0)

箭头函数没有它自己的this,但是它具有封闭执行上下文的this值。箭头函数按词法绑定它们的上下文,因此它实际上是指原始上下文。如果您要命名的话,这称为词汇范围。基本上,它使我们不必在代码中执行.bind(this)。请注意,这是JS中的一项实验性功能,这意味着它尚未被ECMAScript标准接受

因此,您可以按以下方式使用它:

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

在渲染方法中,您可以执行以下操作:

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

答案 3 :(得分:0)

如果要像

那样调用函数
onClick={this.handleItemDelete(i)}

然后像这样编写您的函数

handleItemDelete = i => e => {
    value = e.target.value;
};