簡體   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