这可能是我应该知道的,但是当我传递没有括号的函数时,我不太了解组件的行为。这是我的组件代码。
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);
对于onTitleClick
中的<AppBar>
媒体资源,当我通过handleTitleClick()
时,我会收到预期的行为,但当我通过它handleTitleClick
并点击它时,我收到错误那说Cannot read property 'auth' of undefined
。究竟有什么区别导致handleTitleClick
不了解状态?
答案 0 :(得分:4)
好问题!这里有一些错误。 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
答案 1 :(得分:2)
您需要将this
绑定到您的组件。
constructor(props){
super(props);
this.handleTitleClick = this.handleTitleClick.bind(this);
}
在此之后,您可以不使用括号进行调用。实际上当你用括号调用时,你实际上在渲染上执行了这个函数,这实际上并不是你想要的东西。您只想在单击而不是渲染时调用该函数。因此,请不要使用括号,并在构造函数中绑定您的调用。
<AppBar
...
onTitleClick={this.handleTitleClick}
...
/>