【问题标题】:React: How to set a component in 'active' state one at a time, and remove 'active' from all other component on click?React:如何一次将一个组件设置为“活动”状态,并在单击时从所有其他组件中删除“活动”?
【发布时间】:2021-07-12 13:34:30
【问题描述】:

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

 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}
      />

【问题讨论】:

    标签: javascript reactjs components use-state


    【解决方案1】:

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

    我们有两个案例:

    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>
        );
    }
    

    【讨论】:

      【解决方案2】:

      这里的问题是你总是将活动组件设置为null 任何时候点击它们。

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

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

      在不知道 MyComponent 的情况下很难提供更多指导 - 如果您需要更多解释,请随时分享更多代码。

      【讨论】:

      • 这是2个文件中的长代码,我可以在其他地方与您分享吗?
      • @Aishwariya 确定 - 创建一个 Gist (gist.github.com) 或 CodeSandbox (codesandbox.io) 或类似的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-08
      • 2013-06-08
      • 2020-10-03
      相关资源
      最近更新 更多