【问题标题】:What is the difference between passing a function as a prop with or without parentheses in React?在 React 中将函数作为带或不带括号的 prop 传递有什么区别?
【发布时间】:2018-08-16 06:24:25
【问题描述】:

这可能是我应该知道的,但是当我传递一个不带括号的函数时,我不太了解我的组件的行为。这是我的组件代码。

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';

import AppBar from 'material-ui/AppBar';
import LoginButton from './LoginButton';
import LogoutButton from './LogoutButton';

class Header extends Component {
  renderButton() {
    switch (this.props.auth) {
      case null:
        return
      case false:
        return <LoginButton />
      default:
        return <LogoutButton />
    }
  }



handleTitleClick() {
    return(
      <Link to={this.props.auth ? '/classes' : '/'}>
        QueueMe
      </Link>
    );
  }

  render() {
    const styles = {
      title: {
        cursor: 'pointer',
      },
    };

    return(
      <AppBar
        title={<span style={styles.title}>QueueMe</span>}
        onTitleClick={this.handleTitleClick()}
        iconElementRight={this.renderButton()}
        showMenuIconButton={false}
      />
    );
  }
}

/*
 * @input: redux state
 * Allows the component to access certain piece of the state as props
 * Reducers determine the key in the state
 */
function mapStateToProps(state) {
  return { auth: state.auth };
}

export default connect(mapStateToProps)(Header);

对于&lt;AppBar&gt; 中的onTitleClick 属性,当我传递它handleTitleClick() 时,我得到了预期的行为,但是当我传递它handleTitleClick 并单击它时,我得到一个错误,显示Cannot read property 'auth' of undefined。究竟是什么区别导致handleTitleClick 不知道状态?

【问题讨论】:

  • ReactJS 文档:reactjs.org/docs/…
  • 您检查过this 等于handleTitleClick 的内部吗?
  • @RaphaMex 这正是我的想法,但是当我通过不带括号的函数时出现未定义的错误
  • @DanO 出于某种原因,当我在不带括号的情况下传递函数时,状态不是this 的一部分,但是当我用括号传递函数时,不知道它为什么会这样以及如何去围绕它
  • 没有括号,您实际上并没有调用该函数。不带括号的函数名是对该函数的引用。阅读更多teamtreehouse.com/community/…

标签: reactjs redux react-redux material-ui


【解决方案1】:

您需要将this 绑定到您的组件。

constructor(props){
  super(props);
  this.handleTitleClick = this.handleTitleClick.bind(this);
}

在此之后,您可以不带括号调用。实际上,当您使用括号调用时,您实际上是在 render 上执行了该函数,这实际上可能不是您想要的。您只想在单击而不是渲染时调用该函数。所以使用不带括号并在构造函数中绑定你的调用。

<AppBar
    ...
    onTitleClick={this.handleTitleClick}
    ...
  />

【讨论】:

  • 如果支持的话,我更喜欢新的快捷方式:handleTitleClick = () =&gt; {
【解决方案2】:

好问题!这里有一些问题。 Javascript this 真的很痛苦。问题是你的函数没有绑定。

当您编写onTitleClick={this.handleTitleClick()} 时,您会立即在编译时调用该函数。当您在提供未绑定函数时传递handleTitleClick 时,它没有定义this

有两种可能的解决方案,您可以定义

handleTitleClick = (event) =>
    return(
      <Link to={this.props.auth ? '/classes' : '/'}>
        QueueMe
      </Link>
    );
  }

这使得 handleTitleClick 成为一个箭头函数,箭头函数将它们的 this 绑定到创建它们的闭包中。

如果你不喜欢使用 IIFE 方式,你可以随时使用

constructor(props) {
   super(props)
   this.handleTitleClick = this.handleTitleClick.bind(this)
}

如果您仍然卡住,请查看此内容。 https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56

【讨论】:

  • 太棒了,现在说得通了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-08
  • 2015-08-25
相关资源
最近更新 更多