反应事件处理程序:为什么父绑定不会被子绑定覆盖

时间:2019-06-07 13:22:43

标签: javascript reactjs

我在YouTube上关注了React JS速成课程-2019,但找不到以下问题的答案。

为什么子绑定调用不会覆盖父组件中的方法上下文。

可在此处找到代码库https://github.com/bradtraversy/react_crash_todo

但是为了简化问题,这里有一个小的代码段。

父母

class App extends Component {
  state = {
    todos: []
  }


  // Toggle Complete
  markComplete = (id) => {
    this.setState({ todos: this.state.todos.map(todo => {
      if(todo.id === id) {
        todo.completed = !todo.completed
      }
      return todo;
    }) });
  }

  render() {
    return (
        <TodoItem markComplete={this.markComplete}  />
    );
  }
}

孩子

export class TodoItem extends Component {

  render() {
    const { id, title } = this.props.todo;
    return (
        <input type="checkbox" onChange={this.props.markComplete.bind(this, id)} /> {' '}
    )
  }
}

根据我对绑定https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind的理解 我希望当调用markComplete标记时,“ this”将是子上下文,但它将保留父上下文。

  markComplete = (id) => {
    this.setState({ todos: this.state.todos.map(todo => {
    ^^^^ why it is not child
      if(todo.id === id) {
        todo.completed = !todo.completed
      }
      return todo;
    }) });
  }

我确实了解公共类字段的语法。

做魔术有反应吗? https://github.com/facebook/react/blob/64e1921aab4f7ad7e2f345f392033ffe724e52e9/packages/events/EventPluginHub.js#L148

来自答案@ Li357 https://stackoverflow.com/a/51759791/4322180

4 个答案:

答案 0 :(得分:1)

那是因为您正在使用箭头功能。箭头函数使用的不是“调用方”的“词汇此”。尝试这样编写您的方法,然后绑定应该起作用:

  markComplete(id) {
    this.setState({ todos: this.state.todos.map(todo => {
      if(todo.id === id) {
        todo.completed = !todo.completed
      }
      return todo;
    }) });
  }

这个词:http://es6-features.org/#Lexicalthis

[编辑]

您还可以使用functionmarkComplete = function(id) { /*...*/ }

将函数编写为“经典”函数

答案 1 :(得分:1)

由于MDN在其文档中未提及此内容,因此这里是ECMASript的官方链接,该链接解释了此情况。

https://www.ecma-international.org/ecma-262/6.0/#sec-function.prototype.bind

请注意-> 注意2

如果Target是箭头函数或绑定函数,则后续调用F不会使用传递给此方法的thisArg。

答案 2 :(得分:0)

箭头功能自动绑定到当前上下文,在您的情况下,该上下文将是父上下文。

将其更改为普通函数,并在父构造函数中手动绑定

答案 3 :(得分:0)

您不需要在您的子组件中使用绑定。

  

为什么不是孩子?

由于使用箭头功能时,this上下文是指类本身。 将函数绑定到子组件时,如果要引用this作为子上下文,请不要使用箭头函数。

 markComplete (id) {
    this.setState({ todos: this.state.todos.map(todo => {
      if(todo.id === id) {
        todo.completed = !todo.completed
      }
      return todo;
    }) });
}