I have this setState to control my panel open/close state somewhat similar to this post here. And I'm trying to open one panel at one time so there will be only one true value in the state.
Here's my code:
// Parents component
const [show, setShow] = useState({
1 : false, // id=1 when passed to child component (using another props but
2 : false, // dont worry, I'm passing it correctly)
3 : false, // id=3 and so on...
4 : false,
5 : false,
6 : false
})
//Child component
// id is used to check which panel is in open/close state
const handleShowPanel = (id) => {
const val = !props.show
// props.setShow(prev => ({...prev, [key[0].charCodeAt(0)]: false}))
props.setShow(prev => ({...prev, [id] : val})) //this is the one i'm using
// props.setShow(prev => Object.fromEntries(Object.entries(prev).map(([k, v]) => Number(k) !== id ? [k, !v] : [k, false])))
}
The code that I'm using works perfectly fine opening and closing one panel by another one.
Here's a picture for better illustration, let's say first I opened the Panel 1, after that when I clicked Panel 2 I want to close Panel 1 while opening Panel 2. So I will have to set all other values to false except the panel that I'm opening. It is like accordian mode in ant design
If you only want one panel open at-a-time then why not just store the id of the panel you want open?
The parent component owns both the state and the handler functions to update it, it passes down to each panel the currently opened id and a the callback to toggle open a new panel.
const [showId, setShowId] = useState(null); // <-- initially none open
const handleShowPanel = (id) => {
// if already open, close it, otherwise set to new id to
// close previous and open next
setShowId(showId => showId === id ? null : id);
};
Then when mapping/rendering the panels just check the current panel's id against the currently set showId state value to set the open status/prop accordingly.
In this case, you may not need to keep show state for all panels, only keep the opened panel index try this way
const panels = [
{id:1, name:'name1', description:'description 11'},
{id:1, name:'name2', description:'description 22'},
{id:1, name:'name3', description:'description 33'},
{id:1, name:'name4', description:'description 44'},
{id:1, name:'name5', description:'description 55'},
{id:1, name:'name6', description:'description 66'}
]
const PanelParent = () => {
const [openId, setOpenId] = useState('') //set an id if you need to open a default panel
const handleShowPanel = (id) => {
setOpenIndex(openId == id ? false : id)
}
return <>
{panels.map(d => {
return <Panel data={d} handleShowPanel={handleShowPanel} open={openId == d.id}/>
})}
</>
}