Событие Onblur с setState не разрешает onClick дочернего элемента в React - PullRequest
0 голосов
/ 28 октября 2018

Я имел дело с какой-то проблемой в эти дни назад.Проблема связана с тем, что событие всплывает с реакцией.

Я реализовал раскрывающийся список с некоторыми реагирующими компонентами.Это делается с помощью div, содержащего ul и некоторые элементы li.Мне нужно сделать раскрывающийся список доступным с клавиатуры, чтобы я запускал элементы onblur, onfocus, onkeydown и onclick, чтобы показать и скрыть раскрывающийся список, и использовать его с клавиатурой.

Я запускаю функцию, переданную реквизитами дляреально с вещами show / hide, и когда div фокусируется или нажимается, я показываю выпадающий список, а когда он включен, я скрываю его, изменяя состояние компонента.Проблема в том, что у меня есть некоторые элементы li с функциями onclick для выбора нужной опции.Тем не менее, когда я нажимаю на опцию, событие onblur родительского запуска, оно меняет состояние, а событие onclick элемента li не срабатывает, поэтому я не могу выбрать любой параметр.

Я пытаюсь решить эту проблемуиспользуя событие или распространение событий, но я не мог найти никакого решения.Не могли бы вы мне помочь?

Большое спасибо!

РЕДАКТИРОВАТЬ: Код проблемы:

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}
   />
)
};

1 Ответ

0 голосов
/ 28 октября 2018

Я думаю, что вы должны поднять обработчики состояния и события меню до родительского компонента и сделать дочерние без сохранения состояния.поэтому, когда вы запускаете событие для потомка, он будет запускать обработчик для родителя через опору, так что теперь вы можете установить некоторые флаги для обработки событий (например)

parent (onBlur) (добавить флаг насостояние, чтобы проверить, размыто ли оно и не щелкнуло ли это и наоборот)

-child (щелчок)
-child (клавиатура).

пожалуйста, пингуйте меня, если ответ недостаточно ясен.

...