I have created a component and am using useState to update an area of it where it expands when a button is clicked. When I map multiple instances of this component and click the expand button on one of them, all of them expand. How do I fix this?
Here is my code:
const ContainerMenu: React.FC<ContainerMenuProps> = (props: ContainerMenuProps) => {
const [expanded, setExpanded] = useState(false);
return (
<>
<div className={`docker-container-menu ${expanded}`}>
<button onClick={() => setExpanded(!expanded)} className='chevron-button'>
<Icon path={mdiChevronDown} size={1} />
</button>
{expanded && <div className='docker-container-menu-expanded'>
<button style={{ cursor: "pointer" }} onClick={() => props.startContainer(props.Id)}>
<Icon style={{color: "green"}} path={mdiPlay} size={1} />
</button>
<button style={{ cursor: "pointer" }} onClick={() => props.stopContainer(props.Id)}>
<Icon style={{color: "red"}} path={mdiStop} size={1} />
</button>
</div>}
</div>
</>
)
}
Edit: I’ve added the mapping of the component below to show that there are unique keys (the Id prop) being passed through.
return (
<>
<div className="app-main-container">
<div className="docker-containers">
{containers.map((container: ContainerProps) => {
return (
<Container Id={container.Id} State={container.State} Status={container.Status}
Names={container.Names} Labels={container.Labels}/>
)
})}
</div>
</div>
</>
)
2
Answers
It seems you have one State defined and you are using this one state (the same instance,the same time) in all of your expandable buttons.
As we don’t see your code for the mapping it could be possible that you have not given an ID to each of the expandable button instances.
Try to map them with a explicit key.
Here is a link to a resource where you can read about the problem:
https://medium.com/geekculture/using-reacts-state-to-update-css-dynamically-c9b45570340c
The way i solved this is by making the btn a separate component and pass the state as prop like this:
OK i will show how i do it in my project, the one thing i did not tell you is that i pass a function which has the change state inside it maybe thats the trick:
mapping
expand component
Expand button