我正在尝试按照教程中的描述移动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()}
然后auth登录模式永远不会打开,我没有收到任何错误。我还在console.log
添加了login()
,我可以在控制台中看到它,但实际的登录模式永远不会打开?它适用于第一个示例,但不适用于其他示例。
我试图将其转换为函数的原因是因为我想稍后将登录函数传递给子组件,而我无法这样做而且我认为这是阻止我的根本问题
答案 0 :(得分:5)
bind
不会调用您的函数:
bind()方法创建一个新函数,在调用时,将其this关键字设置为提供的值,并在调用新函数时提供任何前面提供的给定参数序列。 docs
此外,您要将onClick
道具的值设置为login
的返回值。如果要传递对该函数的引用,则必须在没有()
的情况下执行该操作。
您的代码应如下所示:
<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那样。
答案 1 :(得分:2)
假设你有一个容器MyContainer,这个容器呈现一个名为MyView的视图。该视图有一个调用方法的按钮。 MyContainer将把它需要使用的方法传递给MyView。
myContainer中:
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}/>;
}
}
MyView的:
const MyView = ({ myClick }) => {
return <button onClick={myClick} />;
};
MyView.propTypes = {
myClick: PropTypes.func
};
export default MyView;
您将所需的函数从容器传递到视图,视图从props调用其父函数。使用bind()将此范围设置为当前范围,以便在从不同范围调用此范围时,它将成为绑定的范围。当您在渲染中时,您运行不同的范围,因此您必须将函数绑定到当前类范围,以便this.myReallyCoolFunction()指向正确的范围(您的类范围)。
答案 2 :(得分:0)
.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会在传播结束后对其进行调用。