繁体   English   中英

具有setState的Onblur事件不允许React中子级的onClick

[英]Onblur event with setState doesn't allow onClick of child in React

这些天来我正在处理一些问题。 该问题与使用react冒泡的事件有关。

我已经实现了一些反应组件的下拉菜单。 这是通过包含ul和一些li元素的div制成的。 我需要使下拉菜单可以通过键盘访问,所以我触发了onblur,onfocus,onkeydown和onclick元素以显示和隐藏下拉菜单并与键盘一起使用。

我用show / hide东西触发props传递给real的函数,当div处于焦点或单击状态时,我显示下拉列表,当onblur时,我隐藏它以更改组件的状态。 问题是我有一些带onclick函数的li元素来选择所需的选项。 但是,当我单击一个选项时,将触发父对象的onblur事件,它会更改状态,并且li元素的onclick事件不会触发,因此我无法选择任何选项。

我正在尝试使用事件冒泡或传播来解决此问题,但找不到任何解决方案。 请你帮助我好吗?

非常感谢!

编辑:问题的代码:

const Filter = (props: FilterProps) => {
...
<div onBlur={(e) =>
   {props.handleDropdown(e, props.isOpen)}} onKeyDown={(e) => {props.handleKeyDown(e)}} onFocus={(e) => props.handleDropdown(e, props.isOpen)} className={props.isOpen ? "Dropdown Dropdown--multiselection is-open" : "Dropdown Dropdown--multiselection"}>
   <Button className="FilterField Dropdown__trigger Button--secondary" onClick={(e) => props.handleDropdown(e, props.isOpen)}>
   <span className="Dropdown__label">{setLabels(ASSETS, props.selectedAssets)}</span>
   <span className="Dropdown__caret"></span>
   </Button>
   <ul className="Dropdown__menu">
      <li className={checkSelectedAsset(-1, props.selectedAssets).class} onClick={(e) => props.selectAsset(e, -1)}>
      <Translate id="all"/>
      {checkSelectedAsset(-1, props.selectedAssets).isSelected && 
      <span className="Dropdown__menu-item-icon">
         <IconCheck/>
      </span>
      }
      </li>
      <li className="Dropdown__menu-divider"></li>
      {
      (props.assetClasses && props.assetClasses.length > 0) &&
      props.assetClasses.map((asset) => {
      return (
      <li className={checkSelectedAsset(asset, props.selectedAssets).class} onClick={(e) => props.selectAsset(e, asset)}>
      {
      <span>
         <Translate id={`products.${Helper.getType(asset)}`}/>
      </span>
      }{checkSelectedAsset(asset, props.selectedAssets).isSelected && 
      <span className="Dropdown__menu-item-icon">
         <IconCheck/>
      </span>
      }
      </li>
      );
      })
      }
   </ul>
</div>

interface PositionsContainerState {
...
isOpen: boolean;
}   

class Container extends 
React.Component<ContainerProps, ContainerState> {
openCloseDropdown = (event, isOpen: boolean) => {
event.stopPropagation();
if (event.type === "focus") {
this.setState({
dropdownExpanded: true,
focusTriggered: true
});
}
else if (event.type === "blur") {
this.setState({
dropdownExpanded: false,
focusTriggered: false
});
}
else if (event.type === "click") {
if (this.state.focusTriggered) {
this.setState({
dropdownExpanded: isOpen,
focusTriggered: false
});
} 
else {
this.setState({
dropdownExpanded: !isOpen,
});
}
}
};
selectAsset = (event, asset: number) => {
//event.detail.keyboardEvent.preventDefault();
if (asset < 0) {
this.props.dispatch(setFilterAssets([]));
}
else {
let auxSelectedAssets = assign([], this.props.selectedAssets);
if (auxSelectedAssets.indexOf(asset) === -1)
auxSelectedAssets.push(asset);
else
auxSelectedAssets.splice(auxSelectedAssets.indexOf(asset), 1);
this.props.dispatch(setFilterAssets(auxSelectedAssets));
}
}
render() {
return (
<Filter
   handleDropdown={props.openCloseDropdown}
   isOpen={props.isOpen}
   selectAsset={props.selectAsset}
   />
)
};

我认为您应该将菜单的状态和事件处理程序提升到父组件,并使子组件变为无状态。 因此,当您向孩子触发事件时,将通过道具触发父事件处理程序,因此您现在可以放置一些标志来处理事件(像这样)

parent(onBlur)(在状态上添加标志以检查其是否模糊并且未被单击,反之亦然)

-child(单击)
-child(键盘)。

如果答案不清楚,请ping我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM