创建了一张卡片,可以在列表中使用 useState 切换,但它会切换所有项目

Created a card that toggles with useState on a list, but it toggles all the items

组件如下:

import { useState, useEffect } from 'react'

export default function AdminsComponent() {
  const [secondCard, setSecondCard] = useState(false)

  const toggleSetSecondCard = () => {
    setSecondCard(!secondCard)
  }

  const adminsComponent = adminData.map((user) => (
    <li
      key={user.index}
      className="px-4 my-1 lg:pl-8 w-full scale-95 transform transition duration-500 hover:scale-100 text-left"
      onClick={toggleSetSecondCard}
    >
     // codehere
    </li>
      
      {secondCard && (
        <div className="px-4 border-l-4 p-2 bg-accent-0 text-accent-8 pb-4 shadow-lg border-blue">
          // ... codehere
        </div>
      )}

  ))

  return <ul>{adminsComponent}</ul>
}

我删除了它内部的所有东西以简化,但基本上我创建了一个 useState 函数,当我单击任何呈现的 <li> 时,它会在 div 中显示

{secondCard && ()}

但它同时为所有 <li> 切换 div。我想要它在 dividually 只是为了我点击的 <li>。我怎样才能做到这一点?

每个 li 都需要有自己的状态。通过将 useState() 与映射到用户的布尔数组一起使用,或者通过拥有自己的组件和自己的状态,如下所示:

import { useState } from "react";

const Card = (props) => {
  const [secondCard, setSecondCard] = useState(false);

  const toggleSetSecondCard = () => {
    setSecondCard(!secondCard);
  };

  return (
    <>
      <li
        key={props.user.index}
        className="px-4 my-1 lg:pl-8 w-full scale-95 transform transition duration-500 hover:scale-100 text-left"
        onClick={toggleSetSecondCard}
      >
        {props.user.name}
      </li>
      {secondCard && (
        <div className="px-4 border-l-4 p-2 bg-accent-0 text-accent-8 pb-4 shadow-lg border-blue">
          Hi
        </div>
      )}
    </>
  );
};

export default function AdminsComponent() {
  let adminData = [
    { name: "asger", index: 1 },
    { name: "viggo", index: 2 }
  ];

  return (
    <ul>
      {adminData.map((user) => (
        <Card user={user} />
      ))}
    </ul>
  );
}

此解决方案的缺点是一个组件无法更改其他组件的状态,因此如果您想要“全部关闭”或确保一次只显示一张卡片,则需要另一个方法。

以下是如何一次只允许打开一张第二张卡片的示例:

import { useState } from 'react'

export default function AdminsComponent() {
  let adminData = [
    { name: "asger", index: 1 },
    { name: "viggo", index: 2 }
  ];

  const [openCard, setOpenCard] = useState(0);

  return (
    <ul>
      {adminData.map((user) => {
        return (
          <>
            <li
              key={user.index}
              className="px-4 my-1 lg:pl-8 w-full scale-95 transform transition duration-500 hover:scale-100 text-left"
              onClick={() => setOpenCard(openCard == user.index ? 0 : user.index)}
            >
              {user.name}
            </li>
            {openCard == user.index && (
              <div className="px-4 border-l-4 p-2 bg-accent-0 text-accent-8 pb-4 shadow-lg border-blue">
                Hi
              </div>
            )}
          </>
        );
      })}
    </ul>
  );
}

您正在使用一个状态元素来切换整个列表。

该方法的问题是,一旦切换状态,所有元素都会更改。更好的方法是将状态初始化为数组,并根据索引不断调整状态。

import { useState, useEffect } from 'react'

export default function AdminsComponent() {
 const [secondCard, setSecondCard] = useState(Array(adminData.length).fill(false))

 const toggleSetSecondCard = (i) => {
   setSecondCard([...secondCard][i]=!secondCard[i]);
 }

 const adminsComponent = adminData.map((user,i) => (
   <li
     key={user.index}
     className="px-4 my-1 lg:pl-8 w-full scale-95 transform transition duration-500 hover:scale-100 text-left"
     onClick={e=>toggleSetSecondCard(i)}
   >
    // codehere
   </li>
     
     {secondCard && (
       <div className="px-4 border-l-4 p-2 bg-accent-0 text-accent-8 pb-4 shadow-lg border-blue">
         // ... codehere
       </div>
     )}

 ))

 return <ul>{adminsComponent}</ul>
}