如何在 React 子组件中设置事件处理程序
Posted
技术标签:
【中文标题】如何在 React 子组件中设置事件处理程序【英文标题】:How to set event handler in React sub-component 【发布时间】:2014-01-27 10:10:48 【问题描述】:我无法将菜单项连接到事件处理程序。这是一个显示状态随时间变化的 UI 模拟。这是一个下拉菜单(通过 Bootstrap),根菜单项显示当前选择:
[ANN]<click ... [ANN] ... [BOB]<click ... [BOB]
[Ann] [Ann]
[Bob]<click + ajax [Bob]
[Cal] [Cal]
最终目标是根据用户的选择异步更改页面内容。点击 Bob 应该会触发 handleClick
,但不是。
顺便说一句,我对 componentDidMount 调用 this.handleClick();
的方式不太满意,但它现在可以作为从服务器获取初始菜单内容的一种方式。
/** @jsx React.DOM */
var CurrentSelection = React.createClass(
componentDidMount: function()
this.handleClick();
,
handleClick: function(event)
alert('clicked');
// Ajax details ommitted since we never get here via onClick
,
getInitialState: function()
return title: "Loading items...", items: [];
,
render: function()
var itemNodes = this.state.items.map(function (item)
return <li key=item><a href='#' onClick=this.handleClick>item</a></li>;
);
return <ul className='nav'>
<li className='dropdown'>
<a href='#' className='dropdown-toggle' data-toggle='dropdown'>this.state.title</a>
<ul className='dropdown-menu'>itemNodes</ul>
</li>
</ul>;
);
$(document).ready(function()
React.renderComponent(
CurrentSelection(),
document.getElementById('item-selection')
);
);
我几乎可以肯定,我对 javascript 作用域的模糊理解是罪魁祸首,但到目前为止我所尝试的一切都失败了(包括尝试通过 props 传递处理程序)。
【问题讨论】:
【参考方案1】:问题是您正在使用匿名函数创建项目节点,其中this
表示window
。解决方法是将.bind(this)
添加到匿名函数中。
var itemNodes = this.state.items.map(function (item)
return <li key=item><a href='#' onClick=this.handleClick>item</a></li>;
.bind(this));
或者创建this
的副本并使用它来代替:
var _this = this, itemNodes = this.state.items.map(function (item)
return <li key=item><a href='#' onClick=_this.handleClick>item</a></li>;
)
【讨论】:
您也可以将map
的第二个参数传递给this
,它将用作执行映射函数的上下文。
太棒了。非常感谢!我最终将函数参数分解为map
,以使其更具可读性,this
作为第二个参数:var itemNodes = this.state.items.map(this.itemNode, this);
@clozach- 如果这回答了你的问题,你能接受吗?
@clozach 如果您提取到函数中,则不再需要 map 的上下文 obj - 组件上的所有方法无论如何都会自动绑定到当前实例。所以这可以正常工作:var itemNodes = this.state.items.map(this.itemNode)
这个答案对我来说很棒,简洁易懂,而许多文档似乎是为已经知道的人编写的......TY【参考方案2】:
据我了解“Anna”、“Bob”、“Cal”的任务规范,解决方案可以如下(基于 React 组件和 ES6):
Basic live demo is here
import React, Component from "react"
export default class CurrentSelection extends Component
constructor()
super()
this.state =
index: 0
this.list = ["Anna", "Bob", "Cal"]
listLi = list =>
return list.map((item, index) => (
<li key=index>
<a
name=item
href="#"
onClick=e => this.onEvent(e, index)
>
item
</a>
</li>
))
onEvent = (e, index) =>
console.info("CurrentSelection->onEvent()", [e.target.name]: index )
this.setState( index )
getCurrentSelection = () =>
const index = this.state
return this.list[index]
render()
return (
<div>
<ul>this.listLi(this.list)</ul>
<div>this.getCurrentSelection()</div>
</div>
)
【讨论】:
以上是关于如何在 React 子组件中设置事件处理程序的主要内容,如果未能解决你的问题,请参考以下文章
react/flux- 子组件用户事件 - 一切都应该通过调度程序路由吗