React使用map渲染按钮时onClick渲染阶段触发两次、点击无响应
问题根因
你给onClick绑定值的写法有误:onClick = {console.log("show fav city" + item)}中大括号包裹的是立即执行的函数调用,不是事件触发时才执行的回调函数。
- 渲染阶段打印日志:React执行map遍历生成按钮DOM时,每遍历到一个列表项就会当场执行
console.log,不需要点击触发。开发环境下如果开启了React严格模式,组件渲染流程会被重复执行一次做异常检测,所以你会看到日志打印两次,这个重复执行行为只在开发环境存在,生产环境不会触发。 - 点击按钮无输出:
console.log执行后的返回值是undefined,相当于你给按钮的点击事件绑定了一个undefined的监听函数,手动点击时自然没有任何逻辑会执行。
修复代码
两种正确写法任选即可:
- 箭头函数包裹逻辑(写法最简单,适合逻辑简单的场景)
<div className="column"> {this.state.favCts.map( (item, index) => <button key={index} onClick={() => console.log("show fav city" + item)} > {item} </button> )} </div>
- 类组件方法绑定(适合逻辑复杂需要抽离的场景)
首先在组件类中定义事件处理方法:
handleShowCity = (cityName) => { console.log("show fav city" + cityName) }
渲染时绑定方法引用,传入对应城市参数:
<div className="column"> {this.state.favCts.map( (item, index) => <button key={index} onClick={this.handleShowCity.bind(this, item)} > {item} </button> )} </div>
优化建议
- 列表渲染不推荐用遍历下标
index作为key值,如果后续城市列表存在增删、排序操作,会导致DOM渲染状态错乱。你的场景下城市名本身是唯一值,可以直接用key={item}替代。 - React事件绑定的核心规则:
onClick等事件属性后面的大括号中,必须传入函数引用,不能直接写会立即执行的语句,否则就会出现渲染时提前执行、点击无响应的问题。
内容的提问来源于stack exchange,提问作者G lau
相关产品推荐
相关产品推荐

