单击时在映射元素上反应切换样式

React toggle style on mapped element on click

这里是 React 新手。一个非常简单的事情,我似乎做不对。

我想更改我地图中单击的元素上的 class,而不是全部。

例如,如果我单击 id 为 1 的元素,它的 class 应该为 'active-color'。如果我然后单击 id 为 2 的元素,则该元素应采用 class 'active-color',而 id 1 应 not 不再具有此 class .

我尝试了很多不同的解决方案,但似乎无法解决这个问题。它似乎不喜欢我在这里使用我的处理函数中的钩子和 returns 一个错误:TypeError: setActive is not a function.

任何想法或其他解决方案将不胜感激!


const ListItems =  () => {

  const { isActive, setActive} = useState(false)
  const { item, dispatch } = useContext(AppContext);

  const handler = (event) => {
        dispatch({
            type: 'SET_ITEM',
            payload: event.currentTarget.dataset.index,
        });
    setActive(!isActive);
    };


  return (
    <div className="container">
      <h2 className="smallheader">Please choose one</h2>
      <div className="flex flex-center">
      {ITEMS.map((item) =>
        <div className={isActive ? 'active-color' : 'card'} data-index={item.value} key={item.id} onClick={handler}>
        <span
          className="card-header">{item.name}</span>
        <span className="card-description">{item.description}</span>
        </div>
      )}
      </div>
    </div>
  )
};
 
 
export default ListItems;

您的第一个问题是 useState() returns 一个数组,而不是一个对象。这意味着当你 destructure isActivesetIsActive 你需要使用数组解构 []:

const [isActive, setActive] = useState(false);

根据您的 AppContext 设置方式,您可能还需要对项目和分派使用数组解构。您的下一个问题是上述状态仅存储布尔值。如果为真,则映射时渲染的每个值都将为 true。这意味着当 active 设置为 true 时,所有项目都将应用 active class。为了帮助管理这一点,您可以更改状态值以保存活动项目的 ID。然后在你的映射回调函数中,检查当前item id是否与你state中存储的id匹配,如果匹配,使用active-color class,否则使用card class.

const [activeItem, setActiveItem] = useState(-1);

const handler = (itemId) => {
 
  dispatch({ // you may want to conditionally call this,  but I'm basing it off your current logic
    type: 'SET_ITEM',
    payload: itemId,
  });
 
  setActiveItem(currentItem => currentItem === -1 ? itemId : -1); // toggle between -1 and itemPressed to make active state toggleable
};

return (
  <div className="container">
    <h2 className="smallheader">Please choose one</h2>
    <div className="flex flex-center">
      {ITEMS.map((item) =>
        <div className={activeItem === item.id ? 'active-color' : 'card'} key={item.id} onClick={() => handler(item.id)}>
        ...

数组解构需要方括号:

而不是:

const { isActive, setActive} = useState(false)
const { item, dispatch } = useContext(AppContext);

写入:

const [ isActive, setActive] = useState(false)
const [ item, dispatch ] = useContext(AppContext);