[英]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.