我在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;
}) });
}
我确实了解公共类字段的语法。
来自答案@ Li357 https://stackoverflow.com/a/51759791/4322180
答案 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
[编辑]
您还可以使用function
:markComplete = 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;
}) });
}