我知道JavaScript的范围,但可能我完全不理解它们,因为这段代码不起作用。
此代码使用React和Relay Modern框架。
有2个按钮,第一个在queryRender
内,后者传递到Relay Modern QueryRenderer
,第二个按钮传递到后面(参见函数render
)。第二个是工作,第一个不执行clickTest
功能。
(这是实际代码的简化版)
class Candidates extends Component {
static propTypes = {
viewer: PropTypes.object
}
constructor (props) {
super(props)
this.clickTest = this.clickTest.bind(this)
}
clickTest () {
console.log('click works')
}
queryRender ({error, props}) {
if (error) {
return <pre>{error.message}</pre>
} else if (props) {
return (
<div>
<Button onClick={this.clickTest}>this DOESN'T work</Button>
</div>
)
}
return <Loader active>Loading...</Loader>
}
render () {
return (
<div>
<QueryRenderer
environment={environment}
query={query}
render={this.queryRender}
/>
<Button onClick={this.clickTest}>this works</Button>
</div>
)
}
}
query
变量已定义,我只是没有将其包含在摘录中。
当我用匿名的
替换第一个按钮的onClick函数时<Button onClick={() => this.clickTest()}>this DOESN'T work</Button>
然后我得到这样的错误:Uncaught TypeError:_this2.clickTest不是函数
任何人都可以向我解释为什么这段代码会像它那样表现吗?
答案 0 :(得分:1)
在javascript中,this
的含义不是在创建的函数时确定的,而是在调用时确定的。当QueryRenderer调用您的queryRender函数时,它不知道它需要在您的类的上下文中调用它,因此this
将不会引用您认为它所指的内容。
你需要绑定你的queryRender函数,就像你在构造函数中使用clicktest函数一样,或者你需要重新设计queryRender所以它不需要对this
的引用。
答案 1 :(得分:1)
扩展Artur和Nicholas&#39;答案,您需要bind()
这个或使用箭头函数来确保this
指的是组件本身。你已经有了bind方法,这里是箭头函数的一个例子,它摆脱了绑定的需要,因为箭头函数实际上没有绑定这个值,他们使用它们的父节点而不是......
class Candidates extends Component {
static propTypes = {
viewer: PropTypes.object
}
constructor (props) {
super(props)
this.clickTest = this.clickTest.bind(this)
}
clickTest () {
console.log('click works')
}
queryRender = ({error, props}) => {
if (error) {
return <pre>{error.message}</pre>
} else if (props) {
return (
<div>
<Button onClick={this.clickTest}>this DOESN'T work</Button>
</div>
)
}
return <Loader active>Loading...</Loader>
}
render () {
return (
<div>
<QueryRenderer
environment={environment}
query={query}
render={this.queryRender}
/>
<Button onClick={this.clickTest}>this works</Button>
</div>
)
}
}
答案 2 :(得分:0)
箭头功能不会创建新范围,其范围是封闭执行上下文,在这种情况下它是QueryRenderer
范围内您没有此功能。当您将其作为简单函数传递时,范围将是未定义的,我不知道Button
内部的内容。我还没有使用过Rely,也不确定你可以从Rely render方法中引用组件。