【问题标题】:How to toggle class of a single element in a .map() function?如何在 .map() 函数中切换单个元素的类?
【发布时间】:2021-10-12 21:04:52
【问题描述】:

我正在尝试为循环内的特定元素切换类。

const ItemList: React.FC<ListItemUserProps> = (props) => {

  const { items } = props;

  const [showUserOpt, setShowUserOpt] = useState<boolean>(false);

  function toggleUserOpt() {
    setShowUserOpt(!showUserOpt);
  }

  const userOptVisible = showUserOpt ? 'show' : 'hide';

  return (
    <>
      {items.map((t) => (
        <React.Fragment key={t.userId}>
          <div
            className={`item ${userOptVisible}`}
            role="button"
            tabIndex={0}
            onClick={() => toggleUserOpt()}
            onKeyDown={() => toggleUserOpt()}
          >
            {t.userNav.firstName}
          </div>
        </React.Fragment>
      ))}
    </>
  );
};

export default ItemList;

当我单击一个元素时,该类会为每个元素切换。

【问题讨论】:

    标签: reactjs react-native react-redux


    【解决方案1】:

    您可以创建另一个组件,该组件可以拥有自己的状态,可以在不影响其他同级组件状态的情况下进行切换:

    孩子:

    const ItemListItem: React.FC<SomeInterface> = ({ item }) => {
      const [show, setShow] = useState<boolean>(false);
    
      const userOptVisible = show ? "show" : "hide";
    
      const toggleUserOpt = (e) => {
        setShow((prevState) => !prevState);
      };
    
      return (
        <div
          className={`item ${userOptVisible}`}
          role="button"
          tabIndex={0}
          onClick={toggleUserOpt}
          onKeyDown={toggleUserOpt}
        >
          {item.userNav.firstName}
        </div>
      );
    };
    

    家长:

    const ItemList: React.FC<ListItemUserProps> = ({ items }) => {
      return (
        <>
          {items.map((t) => (
            <ItemListItem key={t.userId} item={t} />
          ))}
        </>
      );
    };
    

    【讨论】:

      【解决方案2】:

      如果您只是向元素添加类,我会保持简单并使用处理程序使用纯 JS 切换类。

      const handleClick = (e) => {
         // example of simply toggling a class
         e.currentTarget.classList.toggle('selected');
      };
      

      演示:

      const {
        useState,
      } = React;
      
      // dummy data
      const data = Array(20).fill(null).map((i, index) => `item ${(index + 1).toString()}`);
      
      function App() {
        const [items, setItems] = useState(data);
        
        const handleClick = (e) => {
          e.currentTarget.classList.toggle('selected');
        };
      
        return ( 
          <div> 
            {items.map((item) => (
              <button key={item} onClick={handleClick}>{item}</button>
            ))} 
          </div>
        );
      }
      
      ReactDOM.render( <
        App / > ,
        document.getElementById("app")
      );
      .selected {
         background: red;
      }
      <script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
      <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
      
      
      
      <div id="app"></div>

      【讨论】:

        【解决方案3】:

        我认为最好跟踪索引,以便可以针对列表中的单个项目。就目前而言,boolean 将更改所有人的样式,因为您尚未指定哪个应该获得className

        添加一个useState 挂钩来跟踪它,例如:

        const [activeIndex, setActiveIndex] = useState(null);
        

        然后新建一个函数:

        function handleIndexOnClick(index) {
            setActive(index);
          }
        

        然后在您的map() 函数中添加index。然后,您需要将 index 传递给您的 className 属性和 onClick 函数。该位的最终结果应如下所示:

        {items.map((t, index) => (
                <React.Fragment key={t.userId}>
                  <div
                    className={`item ${activeIndex && items[activeIndex] ? 'show' : 'hide }`}
                    role="button"
                    tabIndex={0}
                    onClick={() => handleIndexOnClick(index)}
                    onKeyDown={() => toggleUserOpt()}
                  >
                    {t.userNav.firstName}
                  </div>
                </React.Fragment>
              ))}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-04-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-20
          • 1970-01-01
          • 2013-09-23
          相关资源
          最近更新 更多