Javascript React事件处理程序:为什么子绑定不覆盖父事件
我在youtube上观看了React JS速成班-2019,但未能找到以下问题的答案 为什么子绑定调用不会覆盖父组件中的方法上下文 代码库可以在这里找到 但为了简化问题,这里有一个小代码片段 母公司Javascript React事件处理程序:为什么子绑定不覆盖父事件,javascript,reactjs,Javascript,Reactjs,我在youtube上观看了React JS速成班-2019,但未能找到以下问题的答案 为什么子绑定调用不会覆盖父组件中的方法上下文 代码库可以在这里找到 但为了简化问题,这里有一个小代码片段 母公司 class App extends Component { state = { todos: [] } // Toggle Complete markComplete = (id) => { this.setState({ todos: this.state
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} />
);
}
}
我确实理解公共类字段语法
你在施魔法吗
从answer@Li357开始,箭头函数自动绑定到当前上下文,在您的情况下,该上下文将是父上下文
将其更改为普通函数,并在父构造函数中手动绑定箭头函数自动绑定到当前上下文,在您的情况下,该上下文将是父上下文
将其更改为普通函数,并在父构造函数中手动绑定,这是因为您使用的是arrow函数。箭头函数使用的“词法this”不是“调用者”。尝试这样编写方法,那么绑定应该可以工作:
markComplete(id) {
this.setState({ todos: this.state.todos.map(todo => {
if(todo.id === id) {
todo.completed = !todo.completed
}
return todo;
}) });
}
这是:
[编辑]
您还可以使用
function
:markComplete=function(id){/*…*/}
将函数编写为“经典”函数,因为您使用的是箭头函数。箭头函数使用的“词法this”不是“调用者”。尝试这样编写方法,那么绑定应该可以工作:
markComplete(id) {
this.setState({ todos: this.state.todos.map(todo => {
if(todo.id === id) {
todo.completed = !todo.completed
}
return todo;
}) });
}
这是:
[编辑]
您还可以使用
function
:markComplete=function(id){/*…*/}
将函数编写为“经典”函数,您不需要在子组件中使用bind
为什么不是孩子
因为当您使用arrow函数时,这个
上下文指的是类本身。
如果要在将函数绑定到子组件时将此作为子上下文引用,请不要使用arrow函数
markComplete (id) {
this.setState({ todos: this.state.todos.map(todo => {
if(todo.id === id) {
todo.completed = !todo.completed
}
return todo;
}) });
}
您不需要在子组件中使用bind 为什么不是孩子 因为当您使用arrow函数时,
这个
上下文指的是类本身。
如果要在将函数绑定到子组件时将此作为子上下文引用,请不要使用arrow函数
markComplete (id) {
this.setState({ todos: this.state.todos.map(todo => {
if(todo.id === id) {
todo.completed = !todo.completed
}
return todo;
}) });
}
由于MDN在其文档中没有提到这一点,这里是解释此案例的ECMAScript的官方链接 注意->注2
如果目标函数是箭头函数或绑定函数,则传递给此方法的thisArg将不会被随后的F调用使用。因为MDN在其文档中没有提到这一点。这里是解释此情况的ECMAScript的官方链接 注意->注2
如果目标是arrow函数或绑定函数,则传递给此方法的thisArg将不会被后续的F调用使用。我理解词法“this”,但这不是也会被绑定调用覆盖吗?不,这是词法this的原形,它“捕获”
this
这样它就不会在以后更改const func=()=>{console.log(this)}
相当于const that=this;const func=function(){console.log(that)}
。这样写的话,我们看到函数中不再使用this
,所以绑定它不会改变任何东西,在这种情况下,它是有意义的。但接下来的问题是。react在将“{this.props.markComplete.bind(this,id)}”传递给实际事件处理程序之前是否在新方法中包装“{this.props.markComplete.bind(this,id)}”?这就是为什么需要绑定以便他知道要传递哪个id的原因?bind
只接受一个参数AFAIK,因此this.props.markComplete.bind(this,id)
与this.props.markComplete.bind(this)
是一样的。我猜你的意思是onChange={()=>this.props.markComplete(id)}
bind
实际上需要不止一个参数,但它通常用于更改this
。我理解词法“this”,但它不是也被bind调用覆盖了吗?不,这是词法的原形,它“捕获”this
这样它就不会在以后更改const func=()=>{console.log(this)}
相当于const that=this;const func=function(){console.log(that)}
。这样写的话,我们看到函数中不再使用this
,所以绑定它不会改变任何东西,在这种情况下,它是有意义的。但接下来的问题是。react在将“{this.props.markComplete.bind(this,id)}”传递给实际事件处理程序之前是否在新方法中包装“{this.props.markComplete.bind(this,id)}”?这就是为什么需要绑定以便他知道要传递哪个id的原因?bind
只接受一个参数AFAIK,因此this.props.markComplete.bind(this,id)
与this.props.markComplete.bind(this)
是一样的。我猜你的意思是onChange={()=>this.props.markComplete(id)}
bind
实际上需要不止一个参数,但它通常用于更改this
。我更感兴趣的是为什么,以及如何更改。这是由于词法作用域-箭头函数中this
的上下文引用类(因此不必将函数绑定到类,因为它们可以在词法作用域/箭头函数中访问)-如果您没有使用arrow函数,则必须将函数绑定到构造函数中的类..-根据OP的要求更新我的答案。我更感兴趣的是为什么以及如何更新。这是由于词法作用域-arrow函数中的此
的上下文引用了类(因此不必将函数绑定到类,因为它们可以在词法作用域/箭头函数中访问)-如果不使用箭头函数,则必须将函数绑定到构造函数中的类..-updatein