Javascript 单击React中可单击组件的外部
我有一个基本组件,如下所示Javascript 单击React中可单击组件的外部,javascript,reactjs,Javascript,Reactjs,我有一个基本组件,如下所示 class List extends React.Component { constructor() { super(...arguments); this.state = { selected: null, entities: new Map([ [0, { 'name': 'kot'} ], [1, { 'name': 'blini'} ] ]) }; } re
class List extends React.Component {
constructor() {
super(...arguments);
this.state = {
selected: null,
entities: new Map([
[0, { 'name': 'kot'} ],
[1, { 'name': 'blini'} ]
])
};
}
render() {
return (<div>
<ul>{this.renderItems()}</ul>
</div>)
}
renderItems() {
return Array.from(this.state.entities.entries()).map(s => {
const [ id, entry ] = s;
return <li
key={id}
onClick={() => this.setState(state => ({ selected: id }))}
style={{
color: id === this.state.selected ? 'red' : 'black'
}}
>{entry.name}</li>
})
}
}
类列表扩展了React.Component{
构造函数(){
超级(…参数);
此.state={
选中:空,
实体:新地图([
[0,{'name':'kot'}],
[1,{'name':'blini'}]
])
};
}
render(){
返回(
{this.renderItems()}
)
}
renderItems(){
返回Array.from(this.state.entities.entries()).map(s=>{
const[id,entry]=s;
返回this.setState(state=>({selected:id}))}
风格={{
颜色:id==this.state.selected?'red':'black'
}}
>{entry.name}
})
}
}
这样做的目的是允许我单击任何元素并选择它。选定的元素将显示为红色
但是,如果发现不是这些元素之一的单击事件,我希望该行为将取消设置任何当前选定的项目
如何在React中实现这一点?在
列表中,您可以添加
componentDidMount() {
window.addEventListener("click", (e) => {
let withinListItems = ReactDOM.findDOMNode(this).contains(e.target);
if ( ! withinListItems ) {
this.setState({ selected: null });
}
});
}
在您的渲染图中,将onClick
更改为
onClick={ (e) => {
// e.stopPropagation();
this.setState({ selected: id });
}
}
你可以签出这个代码笔
编辑:
@kubajz所说的是真的,因此我更新了答案。在您的列表
组件中,您可以添加
componentDidMount() {
window.addEventListener("click", (e) => {
let withinListItems = ReactDOM.findDOMNode(this).contains(e.target);
if ( ! withinListItems ) {
this.setState({ selected: null });
}
});
}
在您的渲染图中,将onClick
更改为
onClick={ (e) => {
// e.stopPropagation();
this.setState({ selected: id });
}
}
你可以签出这个代码笔
编辑:
@kubajz所说的是真的,因此我更新了答案。随机用户的答案是正确的,它可能有一个缺陷-它依赖于stopPropagation
,并且有可能某些代码不再按预期工作-想象一下在页面上收集用户行为并将度量发送到某处-stopPropagation将防止冒泡,因此不会记录单击。另一种方法是检查在事件中单击的内容。目标
:
还有一个很好的实用程序组件,用于在文档级别进行侦听:随机用户的答案是正确的,它可能有一个缺陷-它依赖于stopPropagation
,并且有可能某些代码不再按预期工作-想象一下在页面上收集用户行为并将度量发送到某处-stopPropagation将防止冒泡,因此不会记录单击。另一种方法是检查在事件中单击的内容。目标
:
还有一个很好的实用程序组件,用于在文档级别进行侦听:使列表项成为一个单独的组件,如项
。您的父列表
组件应具有宽度和高度,以占用更多空间并实现其自己的onClick事件。将列表项设置为一个独立的组件,如项
。您的父列表
组件应具有宽度和高度,以占用更多空间并实现其自己的onClick事件。这不会在卸载组件时删除事件侦听器。(事实上,它无法删除事件侦听器;因为它使用一个匿名本地函数来addEventListener
,所以无法检索它来调用removeEventListener
)您应该将事件处理程序放在类方法中(例如,handleWindowClick
),将其绑定到构造函数中(this.handleindowclick=handleindowclick.bind(this)
),并添加删除事件的componentWillUnmount
方法(window.removeEventListener(“单击”,this.handleindowclick)
)。此外,如果父div在作用域内,它将失败。当卸载组件时,它不会删除事件侦听器。(事实上,它无法删除事件侦听器;因为它使用匿名本地函数来addEventListener
,因此无法检索它以调用removeEventListener
)您应该将事件处理程序放在类方法中(例如,handleindowclick
),将其绑定到构造函数中(this.handleindowclick=handleindowclick.bind(this)
),并添加一个删除事件的componentWillUnmount
方法(window.removeEventListener(“单击”,this.handleindowclick)
)。此外,如果父div在范围内,则它将失败