为什么 onClick 会触发多次
Why onClick fires several times
我正在使用 Semantic-ui-react
redux
和 react-router-dom
。在我的组件中,我有导航栏:
<Menu >
<Menu.Item as={Link} to="/" onClick = {this.onNavBarItemCLick()}>
home
</Menu.Item>
<Menu.Item as={Link} to="profile" onClick = {this.onNavBarItemCLick()}>
profile
</Menu.Item>
<Menu.Item as={Link} to="shop" onClick = {this.onNavBarItemCLick()}>
shop
</Menu.Item>
</Menu>
如果我点击其中一个导航项方法 onNavBarItemClick
会触发 3 次。为什么会这样?
因为你不应该在 onClick 属性中立即调用它。使用这个
<Menu.Item as={Link} to="/" onClick = {this.onNavBarItemCLick}>
最后发生了什么,当状态改变时每次调用渲染函数时都会调用 onNavBarItemCLick
因为您立即调用方法,所以您应该只将处理程序传递给 onClick 属性:
as={Link} to="shop" onClick = {this.onNavBarItemCLick.bind(this)}>
解决方案
你需要更换
onClick = {this.onNavBarItemCLick()}
和
onClick = {() => this.onNavBarItemCLick()} // perserving class's this
或者如果您更喜欢绑定符号
onClick = {this.onNavBarItemCLick.bind(this)} // perserving class's this
其他
onClick = {this.onNavBarItemCLick} // not perserving class's this
为什么会这样
发生这种情况是因为当您单击时 render()
会再次调用。
React 在 re-rendering 中非常高效,所以这是它应该发生的事情。
您的实施存在问题,您没有传递方法引用,而是传递了此类方法的返回值。
onClick
属性将一个函数作为值,所以这里有什么问题?
<MyComponent onClick={this.handleClick()} />
使用 this.handleClick()
立即调用该函数并将其 return 值赋给 onClick
。您在这里想要的是像这样
将函数本身提供给 onClick
<MyComponent onClick={this.handleClick} />
但是如果 this.handleClick
使用 this
你可能会在那里遇到另一个错误,因为它不会自动绑定在 React class 中。有一些方法可以解决这个问题,比如在构造函数中绑定 this
,为 handleClick
使用数组函数,或者在将函数传递给 onClick
时直接绑定 this
,例如
<MyComponent onClick={this.handleClick.bind(this)} />
更进一步,您还可以 return handleClick
中的一个函数,这里完全没用。这只是为了说明:
class MyComponent extends React.Component {
handleClick () {
return () => { console.log('I am triggered on click') }
}
render () {
// We call this.handleClick() which returns the function
// that'll be actually called on click.
return <div onClick={this.handleClick()} />
}
}
希望对您有所帮助
当您执行 this.onNavBarItemClick()
时,括号会在该点执行函数。而 this.onNavBarItemClick
会将其视为变量。
所以在上面的代码中,当您执行 onClick = {this.onNavBarItemClick()}
时,该函数会在用户点击它的情况下自行调用。而如果您执行 onClick = {this.onNavBarItemCLick}
,则只有在您单击它时才会调用该函数。
你也可以onClick = {()=>this.onNavBarItemClick()}
。通过这样做,您正在创建一个匿名函数并将其传递给 onClick
.
所以您可以选择 onClick = {this.onNavBarItemClick}
或 onClick = {()=> this.onNavBarItemClick()}
我正在使用 Semantic-ui-react
redux
和 react-router-dom
。在我的组件中,我有导航栏:
<Menu >
<Menu.Item as={Link} to="/" onClick = {this.onNavBarItemCLick()}>
home
</Menu.Item>
<Menu.Item as={Link} to="profile" onClick = {this.onNavBarItemCLick()}>
profile
</Menu.Item>
<Menu.Item as={Link} to="shop" onClick = {this.onNavBarItemCLick()}>
shop
</Menu.Item>
</Menu>
如果我点击其中一个导航项方法 onNavBarItemClick
会触发 3 次。为什么会这样?
因为你不应该在 onClick 属性中立即调用它。使用这个
<Menu.Item as={Link} to="/" onClick = {this.onNavBarItemCLick}>
最后发生了什么,当状态改变时每次调用渲染函数时都会调用 onNavBarItemCLick
因为您立即调用方法,所以您应该只将处理程序传递给 onClick 属性:
as={Link} to="shop" onClick = {this.onNavBarItemCLick.bind(this)}>
解决方案
你需要更换
onClick = {this.onNavBarItemCLick()}
和
onClick = {() => this.onNavBarItemCLick()} // perserving class's this
或者如果您更喜欢绑定符号
onClick = {this.onNavBarItemCLick.bind(this)} // perserving class's this
其他
onClick = {this.onNavBarItemCLick} // not perserving class's this
为什么会这样
发生这种情况是因为当您单击时 render()
会再次调用。
React 在 re-rendering 中非常高效,所以这是它应该发生的事情。
您的实施存在问题,您没有传递方法引用,而是传递了此类方法的返回值。
onClick
属性将一个函数作为值,所以这里有什么问题?
<MyComponent onClick={this.handleClick()} />
使用 this.handleClick()
立即调用该函数并将其 return 值赋给 onClick
。您在这里想要的是像这样
onClick
<MyComponent onClick={this.handleClick} />
但是如果 this.handleClick
使用 this
你可能会在那里遇到另一个错误,因为它不会自动绑定在 React class 中。有一些方法可以解决这个问题,比如在构造函数中绑定 this
,为 handleClick
使用数组函数,或者在将函数传递给 onClick
时直接绑定 this
,例如
<MyComponent onClick={this.handleClick.bind(this)} />
更进一步,您还可以 return handleClick
中的一个函数,这里完全没用。这只是为了说明:
class MyComponent extends React.Component {
handleClick () {
return () => { console.log('I am triggered on click') }
}
render () {
// We call this.handleClick() which returns the function
// that'll be actually called on click.
return <div onClick={this.handleClick()} />
}
}
希望对您有所帮助
当您执行 this.onNavBarItemClick()
时,括号会在该点执行函数。而 this.onNavBarItemClick
会将其视为变量。
所以在上面的代码中,当您执行 onClick = {this.onNavBarItemClick()}
时,该函数会在用户点击它的情况下自行调用。而如果您执行 onClick = {this.onNavBarItemCLick}
,则只有在您单击它时才会调用该函数。
你也可以onClick = {()=>this.onNavBarItemClick()}
。通过这样做,您正在创建一个匿名函数并将其传递给 onClick
.
所以您可以选择 onClick = {this.onNavBarItemClick}
或 onClick = {()=> this.onNavBarItemClick()}