函数未传递给 Button 的原因是什么
What is the reason that function is not passed to a Button
我知道 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 is not a function
任何人都可以向我解释为什么这段代码会这样运行吗?
在 javascript 中,this
的含义不是在 创建函数 时确定的,而是在 时确定的调用。当 QueryRenderer 调用您的 queryRender 函数时,它不知道它需要在您的 class 的上下文中调用它,因此 this
不会引用您认为它所引用的内容。
您要么需要绑定 queryRender 函数,就像您在构造函数中使用 clicktest 函数一样,要么您需要重新设计 queryRender,这样它就不需要引用 this
.
箭头函数不会创建新的作用域,它的作用域包含执行上下文,在这种情况下,它是 QueryRenderer
作用域,您没有此函数。当您将它作为简单函数传递时,范围将是未定义的,我不知道 Button
在里面做了什么。我没有使用过 Rely,不确定您是否可以从 Rely render 方法中引用组件。
要扩展 Artur 和 Nicholas 的答案,您需要 bind()
this 或使用箭头函数来确保 this
指的是组件本身。你已经有了 bind 方法,这里是一个箭头函数的例子,它不需要绑定,因为箭头函数实际上并不绑定 this 值,它们使用它们的父作用域......
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>
)
}
}
我知道 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 is not a function
任何人都可以向我解释为什么这段代码会这样运行吗?
在 javascript 中,this
的含义不是在 创建函数 时确定的,而是在 时确定的调用。当 QueryRenderer 调用您的 queryRender 函数时,它不知道它需要在您的 class 的上下文中调用它,因此 this
不会引用您认为它所引用的内容。
您要么需要绑定 queryRender 函数,就像您在构造函数中使用 clicktest 函数一样,要么您需要重新设计 queryRender,这样它就不需要引用 this
.
箭头函数不会创建新的作用域,它的作用域包含执行上下文,在这种情况下,它是 QueryRenderer
作用域,您没有此函数。当您将它作为简单函数传递时,范围将是未定义的,我不知道 Button
在里面做了什么。我没有使用过 Rely,不确定您是否可以从 Rely render 方法中引用组件。
要扩展 Artur 和 Nicholas 的答案,您需要 bind()
this 或使用箭头函数来确保 this
指的是组件本身。你已经有了 bind 方法,这里是一个箭头函数的例子,它不需要绑定,因为箭头函数实际上并不绑定 this 值,它们使用它们的父作用域......
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>
)
}
}