React:在另一个函数内部时无法调用 prop 函数?
React: Can't call prop function when it is inside of another function?
我正在尝试按照他们的教程中的说明移动 Auth0 登录功能。如果我这样使用它,我就能让它工作:
<button className="btn" onClick={this.props.route.auth.login.bind(this)}>test</button>
但是如果我设置按钮来调用我在渲染函数上方定义的函数,如下所示:
login() {
this.props.route.auth.login.bind(this);
}
并将onclick改成这样:
onClick={this.login()}
或
onClick={() => this.login()}
然后身份验证登录模式永远不会打开,我也没有收到任何错误。我还添加了一个 console.log
到 login()
并且我可以在控制台中看到它,但是实际的登录模式永远不会打开?它适用于第一个示例,但不适用于其他示例。
我试图将其移动到一个函数中的原因是我想稍后将登录函数向下传递到一个子组件中,但我无法这样做,我相信这是根本问题阻止我。
bind
没有调用你的函数:
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called. docs
此外,您正在将 onClick
属性的值设置为 login
的 return 值。如果要传递对函数的引用,则必须在没有 ()
.
的情况下进行
您的代码应如下所示:
<button className="btn" onClick={() => this.login()}>test</button> <!-- You need to keep a reference to `this`, hence the binding -->
然后:
login() {
this.props.route.auth.login();
}
我编辑了答案,使其使用箭头函数。但是,我不想这样做,因为它使代码有点麻烦,而且 bind
构造函数中的所有函数,就像 @patrick-w-mcmahon 所做的那样。
假设您有一个容器 MyContainer,这个容器呈现一个名为 MyView 的视图。该视图有一个调用方法的按钮。 MyContainer 将把它需要使用的方法传递给 MyView。
我的容器:
class MyContainer extends React.Component {
constructor(props) {
super(props);
this.myFunc = this.myFunc.bind(this);
}
myFunc() {
console.log("hello world");
}
render() {
return <MyView myClick={this.myFunc}/>;
}
}
我的观点:
const MyView = ({ myClick }) => {
return <button onClick={myClick} />;
};
MyView.propTypes = {
myClick: PropTypes.func
};
export default MyView;
您将所需的函数从容器传递给视图,视图从 props 调用其父函数。 bind() 的使用将此范围设置为当前范围,以便当您从不同的范围调用它时,它将成为绑定的范围。当您在渲染中时,您 运行 一个不同的范围,因此您必须将您的函数绑定到当前 class 范围,以便 this.myReallyCoolFunction() 指向正确的范围(您的 class范围)。
.bind()
只会绑定对象和参数,但不会调用 (运行) 函数。
TL;DR 只需使用 .call()
而不是 .bind()
而不是 .bind()
你可以使用
.call(this, args)
与 bind 基本相同,只是 call
将调用 (运行) 函数。
您也可以使用 .apply()
,它与 .call()
基本相同,但使用带有参数的数组而不是像 .call()
这样的对象
这样你就可以避免 jsx render() 中的箭头函数
并保持反应的思路。
类似 ->
login() {
this.props.route.auth.login.call(this);
}
当你通过 return(JSX) 调用 props 函数时,React 会在传播结束后负责调用它。
我正在尝试按照他们的教程中的说明移动 Auth0 登录功能。如果我这样使用它,我就能让它工作:
<button className="btn" onClick={this.props.route.auth.login.bind(this)}>test</button>
但是如果我设置按钮来调用我在渲染函数上方定义的函数,如下所示:
login() {
this.props.route.auth.login.bind(this);
}
并将onclick改成这样:
onClick={this.login()}
或
onClick={() => this.login()}
然后身份验证登录模式永远不会打开,我也没有收到任何错误。我还添加了一个 console.log
到 login()
并且我可以在控制台中看到它,但是实际的登录模式永远不会打开?它适用于第一个示例,但不适用于其他示例。
我试图将其移动到一个函数中的原因是我想稍后将登录函数向下传递到一个子组件中,但我无法这样做,我相信这是根本问题阻止我。
bind
没有调用你的函数:
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called. docs
此外,您正在将 onClick
属性的值设置为 login
的 return 值。如果要传递对函数的引用,则必须在没有 ()
.
您的代码应如下所示:
<button className="btn" onClick={() => this.login()}>test</button> <!-- You need to keep a reference to `this`, hence the binding -->
然后:
login() {
this.props.route.auth.login();
}
我编辑了答案,使其使用箭头函数。但是,我不想这样做,因为它使代码有点麻烦,而且 bind
构造函数中的所有函数,就像 @patrick-w-mcmahon 所做的那样。
假设您有一个容器 MyContainer,这个容器呈现一个名为 MyView 的视图。该视图有一个调用方法的按钮。 MyContainer 将把它需要使用的方法传递给 MyView。
我的容器:
class MyContainer extends React.Component {
constructor(props) {
super(props);
this.myFunc = this.myFunc.bind(this);
}
myFunc() {
console.log("hello world");
}
render() {
return <MyView myClick={this.myFunc}/>;
}
}
我的观点:
const MyView = ({ myClick }) => {
return <button onClick={myClick} />;
};
MyView.propTypes = {
myClick: PropTypes.func
};
export default MyView;
您将所需的函数从容器传递给视图,视图从 props 调用其父函数。 bind() 的使用将此范围设置为当前范围,以便当您从不同的范围调用它时,它将成为绑定的范围。当您在渲染中时,您 运行 一个不同的范围,因此您必须将您的函数绑定到当前 class 范围,以便 this.myReallyCoolFunction() 指向正确的范围(您的 class范围)。
.bind()
只会绑定对象和参数,但不会调用 (运行) 函数。
TL;DR 只需使用 .call()
而不是 .bind()
而不是 .bind()
你可以使用
.call(this, args)
与 bind 基本相同,只是 call
将调用 (运行) 函数。
您也可以使用 .apply()
,它与 .call()
基本相同,但使用带有参数的数组而不是像 .call()
这样你就可以避免 jsx render() 中的箭头函数 并保持反应的思路。
类似 ->
login() {
this.props.route.auth.login.call(this);
}
当你通过 return(JSX) 调用 props 函数时,React 会在传播结束后负责调用它。