将嵌套对象的所有值设置为FALSE,只有一个除外

2022-04-12 00:00:00 reactjs javascript react-hooks antd

我使用setState来控制面板的打开/关闭状态,这与this post here有点类似。我正在尝试open one panel at one time,以便state中只有一个真值。
以下是我的代码:

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

我使用的代码可以很好地一个接一个地打开和关闭面板。
这里有一个picture for better illustration,假设我首先打开了Panel 1,然后当我点击Panel 2时,我想关闭面板1,同时opening Panel 2。因此,我必须将除要打开的面板以外的所有其他值设置为FALSE。类似于accordian mode in ant design


解决方案

如果一次只想打开一个面板,为什么不只存储要打开的面板的ID?

父组件拥有状态和处理程序函数以更新它,它向下传递当前打开的id和用于切换打开新面板的回调。

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

然后,在映射/渲染面板时,只需对照当前设置的showId状态值检查当前面板的id,即可相应地设置打开状态/属性。

相关文章