React Hook选择带有图标的多个项目

问题描述 投票:0回答:1

我正在尝试实现一个包含许多项目的弹出窗口,用户可以在其中进行多项选择。当用户单击某个项目时,右侧会显示一个超棒的字体图标。

用户可以选择多个项目,并且右侧显示一个图标,表明已被选中。单击时此图标切换。我的问题是我的事件处理程序与所有项目绑定在一起,每当我单击一个项目时,都将被选中。

我是新来的钩住并做出反应。我也试图在数组中分配所选项目的ID。它不会追加。

const SettingsComponent = (props) => {
const urlStofTyper = stofTyperUrl; 
const stofTyper = [];
const [isPopoverOpen, setPopoverOpen] = useState(false);

const [isItemChecked, setItemChecked] = useState(false);

const [error, setError] = useState(null);
const [loading, setLoading] = useState(null);
const [stoftype, setStoftyper] = useState({ DataList: [] });

const toggle = () => setPopoverOpen(!isPopoverOpen);

const sectionClicked = (e) => {
setItemChecked(!isItemChecked);
let secId = e.target.parentNode.getAttribute("data-section");   
if (!isItemChecked) {
    stofTyper.push(secId);
   } else {
    stofTyper.filter((sec) => sec == secId);
  }
};

useEffect(() => {
fetchStoftyper({ setError, setLoading, setStoftyper });
}, []);

const fetchStoftyper = async ({ setError, setLoading, setStoftyper }) => {
try {
    setLoading(true);
    const response = await Axios(urlStofTyper);
    const allStofs = response.data;
    setLoading(false);
    setStoftyper(allStofs);
  } catch (error) {
    setLoading(false);
    setError(error);
  }
};

return (
<React.Fragment>
  <div className='list-header-icons__fontawesome-icon' id='PopoverClick'>
    <FontAwesomeIcon icon={faCog} />
  </div>
  <Popover
    isOpen={isPopoverOpen}
    placement='bottom'
    toggle={toggle}
    target='PopoverClick'>
    <PopoverHeader>formatter</PopoverHeader>
    <div className='popover-body'>
      <ul className='individual-col--ritzau__dropdown-menu-settings'>
        {stoftype.DataList.map((item) => (
          <li key={item.Id} className='section-items'>
            <a
              onClick={sectionClicked}                 
              className='dropdown-item'                 

              data-section={item.Sections[0].SectionId}
              data-format={
                item.Formats.length > 0
                  ? item.Formats[0].FormatId
                  : ""
              }
              aria-selected='false'>
              <span className='formatter-name'>
                {item.Name}
              </span>
              {isItemChecked && (
                <span className='formatter-check-icon'>
                  <FontAwesomeIcon icon={faCheck} size='lg' />
                </span>
              )}
            </a>
          </li>
        ))}
      </ul>
    </div>
  </Popover>
</React.Fragment>
);
reactjs react-hooks
1个回答
0
投票

现在,您正在使用一个布尔变量来检查是否应显示图标,因为DataList中的每个项目都应具有其自己的单独指示器,所以该图标将不起作用。

一种可能的解决方案是为此目的使用new Map()并将item.id作为和将索引和true/false作为值存储,因此您选择的状态将是这样的:

Map(3) {1 => true, 2 => true, 3 => false}

之后,您可以检查是否应按如下所示显示图标:

!!selected.get(item.id) 

如果HashTable中的值为true,则返回true;如果为false或根本不存在,则返回false。这应该足以实现您要求的功能。

对于真实的示例,您可以检查flatlist-selectable from official Facebook docs。它们显示了如何使用此技术实现多重选择。希望对您有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.