jus*_*der 4 javascript reactjs
我有一个react组件,它使用单独的OnClick呈现一个列表项.
为了找出单击了哪个项,处理程序接受一个参数.处理程序确实被调用 - 但无论单击哪个项目 - 控制台始终记录item3(就像单击item3一样).我在这做错了什么?
class Item {
constructor(props) {
super(props);
this.onItemClickHandler = this.onItemClickHandler.bind(this)
}
onItemClickHandler (itemName) {
console.log("Clicked " + itemName)
}
render() {
this.items = ["item1", "item2", "item3"]
var lis = []
for (var liName in this.items) {
var liName2 = this.items[liName]
console.log("Adding " + this.items[liName])
lis.push(<li className="item-ListItem" key={this.items[liName]} onClick={() => this.onItemClickHandler(this.items[liName])}><span><a href="#">{this.items[liName]}</a></span></li>)
}
return (
<div className="item">
<label className="item-Header"><u>items</u></label>
<ul className="item-List">
{lis}
</ul>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
这一行:
onClick={() => this.onItemClickHandler(this.items[liName])}>
Run Code Online (Sandbox Code Playgroud)
似乎是正确的.
问题是您没有this.items[liName]正确捕获值,因为当您到达第三项迭代时,onClick处理程序将始终具有this.items[liName]设置为第三项的值.
解决方案是使用闭包来正确捕获值,我编辑了您的代码并在此链接中创建了一个完整的示例
https://codesandbox.io/s/3xrp6k9yvp
下面用解决方案编写示例代码
class App extends Component {
constructor(props) {
super(props);
this.onItemClickHandler = this.onItemClickHandler.bind(this);
}
onItemClickHandler(itemName) {
console.log("Clicked " + itemName);
}
render() {
this.items = ["item1", "item2", "item3"];
var lis = [];
for (var liName in this.items) {
var liName2 = this.items[liName];
console.log("Adding " + this.items[liName]);
//the clickHandler function here is the solution we created a function that get executed immediately each iteration and return a new function that has the correct value of `this.items[liName]` saved
var clickHandler = (item => {
return event => {
this.onItemClickHandler(item);
};
})(this.items[liName]);
lis.push(
<li
className="item-ListItem"
key={this.items[liName]}
onClick={clickHandler} // here we use the clickHandler function directly
>
<span>
<a href="#">{this.items[liName]}</a>
</span>
</li>
);
}
return (
<div className="item">
<label className="item-Header">
<u>items</u>
</label>
<ul className="item-List">{lis}</ul>
</div>
);
}
}
Run Code Online (Sandbox Code Playgroud)
有关闭包的更多信息和示例,请检查此链接
编辑我们可以let在ES6 中使用,而不是var在@ArchNoob提到的for循环中使用,因为使用let将使liName块作用域
| 归档时间: |
|
| 查看次数: |
1465 次 |
| 最近记录: |