React:如何在 'active' 状态下一次设置一个组件,并在单击时从所有其他组件中删除 'active'?

React: How to set a component in 'active' state one at a time, and remove 'active' from all other component on click?

我想将特定组件设置为单击时激活,并在单击其他组件时更新活动组件。 目前,这两个组件都处于活动状态。我想从之前单击的组件中删除活动状态。

 const [activeComponent, setActiveComponent] = useState(null);

  const updateActiveComponent = (e, active_component) => {
    if (active_component.id != activeComponent?.id) {
      setActiveComponent(active_component);
    } else {
      closeActiveComponent();
    }
  };
  const closeActiveComponent = () => {
    setActiveComponent(null);
  };
<MyComponent
        key={index}
        card={card}
        clickHandler={updateActiveComponent}
      />

这里的问题是,只要单击其中任何一个,您总是将活动组件设置为 null

如果想根据它是否处于活动状态来改变 MyComponent 的呈现方式,您需要向它传递一个道具来告诉它这一点。假设您通过遍历某些数据来渲染组件:

{cards.forEach(card =>
  <MyComponent
    key={index}
    card={card}
    clickHandler={updateActiveComponent}
    isActive={activeComponent === card.id} />
)}

不知道 MyComponent 看起来像什么,很难提供更多指导 - 如果您需要更多解释,请随时分享更多代码。

为了更笼统,让我们假设您不仅有两个组件,而且有任意数量的组件。

我们有2个案例:

  1. 组件用作单选按钮。一次只能激活一个组件。
  2. 组件用作复选框按钮。多个组件可以处于活动状态。

据我了解,您遇到的是第一种情况。因此,为了使其正常工作,我们需要存储活动组件的 ID。

import { useState } from 'react'

const Component = ({ isActive, onClick }) => {
    return <div onClick={onClick}> {isActive ? 'Active' : 'Not active'} </div>
}

const Page = () = {
    // -1 means that we have not set any component to the active state
    const [activeElement, setActiveElement] = useState(-1);

    const updateActiveElement = (id) => {
        setActiveElement(activeElement !== id ? id : -1);
    }

    return (
        <div>
            <Component active={0 === activeElement} onClick={() => updateActiveElement(0)} />
            <Component active={1 === activeElement} onClick={() => updateActiveElement(1)} />
        </div>
    );
}

对于复选框类型的情况,我们需要单独存储每个组件的状态,也就是说,我们需要创建每个组件状态的数组。

import { useState } from 'react'

const Component = ({ isActive, onClick }) => {
    return <div onClick={onClick}> {isActive ? 'Active' : 'Not active'} </div>
}

const Page = ({ amountComponents }) = {
    const [elementStates, setElementStates] = useState(Array(amountComponents).fill(false));

    const updateActiveElement = (id) => {
        setActiveElement(elementStates.map((isActive, index) => index === id ? !isActive : isActive ));
    }

    return (
        <div>
            {elementStates.map((isActive, id) => (
                <Component active={isActive} onClick={() => updateActiveElement(id)} />
            )}
        </div>
    );
}