2016-08-22 48 views
0

我最近开始学习React,并且在将回调附加到子元素后,我在父元素中丢失了“this”的引用。我正在构建一个简单的任务,并在检查时进行。我将它发送回父项,以便父项可以将其删除并将状态重新分配给没有元素的新数组。但是,我没有访问this.state.todosTask。我弄不明白。 以下是我的代码。REACT React如何在回调后访问正确的“this”

Parent Element TodoList 

constructor(props){ 
    super(props); 
    this.state ={ 
     todosTask: props.todos 
    } 
    } 
    handleCheckedTask(task){ 
    console.log("Now Im in the todost"+task) 
    this.state.todosTask //= Undefined 
    } 
    render(){ 
    return(
     <div> 
     <h4>Todo List</h4> 
     <div className="form-check"> 
     <label className="form-check-label"> 
      {this.state.todosTask.map((todoElement)=>{ 
       return <Todo todo={todoElement} key={todoElement.id} onCheckedTask={this.handleCheckedTask}/> 
      })} 
     </label> 
     </div> 
     </div> 
    ) 
    } 

辅元件

completed(event){ 
    let self = this 
    let task = self.props.todo.task 
    let id = self.props.todo.id 
    console.log(self.refs.complete) 
    this.props.onCheckedTask({id:id,task:task}) 
    } 
    render(){ 
    return(
     <div> 
     <input 
     className="form-check-input" 
     type="checkbox" 
     ref="complete" 
     onChange={this.completed.bind(this)}/> 
     {this.props.todo.task} 
     </div> 
    ) 
    } 
} 

回答

1

您需要将构造函数中的handleCheckedTask与此绑定。

说明:在JavaScript函数和方法中,不像其他语言那样绑定到包含对象,就像在Java中一样。在javascript this是动态的,它(主要)是指“函数的调用者”。对于大多数情况,这并没有什么不同,因为我们通常通过包含对象调用方法,如console.log("foo")。但有时候,我们想要将该函数作为回调函数传递,在这种情况下,调用者不是定义它的对象,而是使用回调函数的对象。幸运的是我们有2种方法来解决这个问题:

  1. 绑定方法的一个对象,.bind()
  2. 若没有通过this的功能和从词汇方面得到它。 (即使用箭头功能)。

constructor(props){ 
    super(props); 
    this.state = { 
     todosTask: props.todos 
    }; 
    this.handleCheckedTask = this.handleCheckedTask.bind(this); 
} 

或者,您可以使用属性初始值设定项来定义您的处理程序。

handleCheckedTask = (task) => { 
    console.log("Now Im in the todost"+task) 
    this.state.todosTask //= Undefined 
    } 

您可以查看详细信息here

编辑:我删除,我说,回调的调用者是在呼唤它的对象的一部分。通常对于回调,this未定义为正常功能(不是箭头功能)。对于箭头函数this从闭包中恢复,也就是从定义它的词法上下文中恢复。

+0

完美。将它绑定到构造函数给了我整个类的控制权。我很困惑,为什么我必须手动绑定它。你可以请解释当我手动绑定它在构造函数中发生了什么。 –

+0

我为我的回复添加了一个解释。 –

0

ES6没有自动此绑定。所以,这应该在构造函数中手动绑定。

constructor(props){ 
    super(props); 
    this.state = { 
     todosTask: props.todos 
    }; 
    this.handleCheckedTask = this.handleCheckedTask.bind(this); 
}