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个案例:
- 组件用作单选按钮。一次只能激活一个组件。
- 组件用作复选框按钮。多个组件可以处于活动状态。
据我了解,您遇到的是第一种情况。因此,为了使其正常工作,我们需要存储活动组件的 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>
);
}
我想将特定组件设置为单击时激活,并在单击其他组件时更新活动组件。 目前,这两个组件都处于活动状态。我想从之前单击的组件中删除活动状态。
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个案例:
- 组件用作单选按钮。一次只能激活一个组件。
- 组件用作复选框按钮。多个组件可以处于活动状态。
据我了解,您遇到的是第一种情况。因此,为了使其正常工作,我们需要存储活动组件的 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>
);
}