简体   繁体   English

React:当它在另一个函数里面时,不能调用prop函数吗?

[英]React: Can't call prop function when it is inside of another function?

I am trying to move over the Auth0 login function as described in their tutorial. 我正在尝试按照他们的教程中的描述移动Auth0登录功能。 I am able to get it work if I use it like this: 如果我像这样使用它,我能够使它工作:

<button className="btn" onClick={this.props.route.auth.login.bind(this)}>test</button>

but if I set up the button to call a function I define above the render function like this: 但如果我设置按钮来调用一个函数我在上面定义了渲染函数,如下所示:

  login() {
   this.props.route.auth.login.bind(this);
  }

And change the onclick to be like this: 并改变onclick如下:

onClick={this.login()}

or 要么

onClick={() => this.login()}

Then the auth login modal never opens and i receive no error. 然后auth登录模式永远不会打开,我没有收到任何错误。 Also i added a console.log to login() and I can see it in the console, but the actual login modal never opens? 我还在console login()添加了一个console.log ,我可以在控制台中看到它,但实际的登录模式永远不会打开? It works in the first example, but not in the others. 它适用于第一个示例,但不适用于其他示例。

The reason I am attempting to move this into a function is because I would like to pass the login function down into a child component later, and I was unable to do so and I believe this to be the root issue thats preventing me. 我试图将其转换为函数的原因是因为我想稍后将登录函数传递给子组件,而我无法这样做,我相信这是阻止我的根本问题。

bind does not call your function: 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. bind()方法创建一个新函数,在调用时,将其this关键字设置为提供的值,并在调用新函数时提供任何前面提供的给定参数序列。 docs 文档

Also, you are setting the value of onClick prop to the return value of login . 此外,您将onClick prop的值设置为login的返回值。 If you want to pass a reference to the function, you have to do it without the () . 如果要传递对函数的引用,则必须在没有()情况下执行此操作。

Your code should look like this: 您的代码应如下所示:

<button className="btn" onClick={() => this.login()}>test</button> <!-- You need to keep a reference to `this`, hence the binding -->

Then: 然后:

login() {
   this.props.route.auth.login();
}

I edited the answer so that it uses an arrow function. 我编辑了答案,以便它使用箭头功能。 However, I prefer not doing that, since it makes the code a bit cumbersome, and rather bind all the functions in the constructor, like @patrick-w-mcmahon did. 但是,我不喜欢这样做,因为它使代码有点麻烦,而是bind构造函数中的所有函数,就像@ patrick-w-mcmahon那样。

Let's say you have a container MyContainer and this container renders a view called MyView. 假设你有一个容器MyContainer,这个容器呈现一个名为MyView的视图。 This view has a button that calls a method. 该视图有一个调用方法的按钮。 MyContainer is going to pass to the MyView the method it needs to use. MyContainer将把它需要使用的方法传递给MyView。

MyContainer: 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;

You pass the needed function from the container to the view and the view calls its parents function from props. 您将所需的函数从容器传递到视图,视图从props调用其父函数。 the use of bind() sets this scope to the current scope so that when you call this from a different scope it is going to be the scope of the bind. 使用bind()将此范围设置为当前范围,以便在从不同范围调用此范围时,它将成为绑定的范围。 When you are in the render you run a different scope so you must bind your functions to the current class scope so that this.myReallyCoolFunction() is pointing to the correct scope (your class scope). 当您在渲染中时,您运行不同的范围,因此您必须将函数绑定到当前类范围,以便this.myReallyCoolFunction()指向正确的范围(您的类范围)。

.bind() will only bind the object and arguments but won't call (run) the function. .bind()只会绑定对象和参数,但不会调用(运行)该函数。

TL;DR Just use .call() instead of .bind() TL; DR只需使用.call()而不是.bind()

instead of .bind() you can use .call(this, args) which is basicaly the same as bind only that call will call (run) the function. 而不是.bind()你可以使用.call(this, args) ,它基本上与bind只相同, call将调用(运行)函数。

you could also use .apply() , which is basicaly the same as .call() but takes an array with the arguments instead of object like .call() 你也可以使用.apply()其是basicaly相同.call()但需要与参数的,而不是像对象的阵列.call()

this way you can avoid arrow functions in you jsx render() and kind of keeping the line of thought with react. 这样你可以避免jsx render()中的箭头函数,并保持思路与反应。

something like -> 像 - >

  login() {
   this.props.route.auth.login.call(this);
  }

When you call props function through return(JSX) React takes care of calling it once propagation ends. 当你通过return(JSX)调用props函数时,React会在传播结束后负责调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM