[英]How to handle active state of multiple dropdown menus in react?
我有一個組件Dropdowns
呈現一組下拉菜單。
當呈現多個菜單時,單擊下拉菜單會同時打開所有菜單。 如何確保只切換一個下拉菜單的活動 state?
Options
屬性決定了有多少Dropdowns
被渲染。 id
只是用於開發,所以我可以更容易地在 devtools 中找到它,如果我在一頁上有多個Dropdowns
。
import React, { useState } from 'react';
import * as style from './Dropdown.module.css';
const Dropdown = (props) => {
const { options, id } = props;
const [active, setActive] = useState(false);
const [selectedOption, setSelectedOption] = useState(0);
const handleActive = () => {
setActive(!active);
};
const setSelectedThenCloseDropdown = (index, filter, item) => {
filter.handler(item);
setSelectedOption(index);
setActive(!active);
};
const handleKeyDown = (index, filter, item) => (e) => {
switch (e.key) {
case `Escape`:
setActive(false);
break;
case ' ':
case 'SpaceBar':
case 'Enter':
e.preventDefault();
setSelectedThenCloseDropdown(index, filter, item);
break;
default:
break;
}
};
return (
<>
<div className={style.dropdownWrapper} id={id}>
{options.map((option) => {
return (
<div key={option.current.id + option.current.name} className={style.dropdownWrapper}>
<div className={style.dropdownContainer}>
<button
role="button"
onClick={handleActive}
aria-haspopup="listbox"
aria-expanded={active}
type="button"
className={style.dropdownToggle}>
{option.current.name}
</button>
{active && (
<div
role="listbox"
aria-activedescendant={option[selectedOption]}
tabIndex={-1}
className={style.dropdownMenu}>
{option.list.map((item, index) => {
/* istanbul ignore next */
return (
<a
role="option"
tabIndex={0}
onKeyDown={handleKeyDown(index, option, item)}
aria-selected={selectedOption == index}
className={style.dropdownItem}
key={item.name + option.current.name}
onClick={() => {
option.handler(item);
setActive(false);
setSelectedOption(index);
}}>
{item.name}
</a>
);
})}
</div>
)}
</div>
</div>
);
})}
</div>
</>
);
};
export default Dropdown;
您可以將“活動”掛鈎設置為 object 以存儲活動下拉列表的狀態和 ID。
const [活躍,setActive] = useState({id:null,狀態:假});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.