我正在使用Material UI Accordian(来自文档的受控示例),并且我希望默认情况下打开所有面板。我已经能够通过创建如下状态对象来实现这一点。但是,我认为我用于更新handleChange上状态的方法很笨拙。
有没有更好的方法来写这个?
const [state, setstate] = useState({
panel1: true,
panel2: true,
panel3: true,
panel4: true,
});
const handleChange = (panel: string) => (event: React.ChangeEvent<{}>, isExpanded: boolean) => {
switch (panel) {
case "panel1":
setstate({ ...state, panel1: state.panel1 ? false : true });
break;
case "panel2":
setstate({ ...state, panel2: state.panel2 ? false : true });
break;
case "panel3":
setstate({ ...state, panel3: state.panel3 ? false : true });
break;
case "panel4":
setstate({ ...state, panel4: state.panel4 ? false : true });
break;
default:
break;
}
};
答案 0 :(得分:0)
改为使用数组:
const [panels, setPanels] = useState(new Array(4).fill(true));
const handleChange = (panelIndex: number) => () => {
const newPanels = [...panels];
newPanels[panelIndex] = !newPanels[panelIndex];
setPanels(newPanels);
};
然后使用例如handleChange(0)
和handleChange(2)
代替handleChange('panel1')
和handleChange('panel3')
。
答案 1 :(得分:0)
您可以这样操作,其中panel in state
代替了default
中的switch..case
const [state, setstate] = useState({
panel1: true,
panel2: true,
panel3: true,
panel4: true
})
const handleChange = (panel: string) => (
event: React.ChangeEvent<{}>,
isExpanded: boolean
) => {
panel in state &&
setstate(prevState => ({
...prevState,
[panel]: state[panel] ? false : true
}))
}
答案 2 :(得分:0)
如果仅将“受控”模式用于切换打开/关闭,则可以将默认的手风琴扩展到新组件。将打开/关闭状态恢复为自己的状态。
const NewAccordion = ({ initialOpen = true, ...restProps }) => {
const [expanded, setExpanded] = React.useState(initialOpen)
const toggle = (event, isExpaneded) => setOpened(!isExpaneded)
return (
<Accordion expanded={expaneded} onChange={toggle} {...restProps} />
)
}
如果仍然要使用对象,则只需覆盖当前面板的状态即可。无需使用开关盒
const [state, setState] = React.useState({
panel1: true,
panel2: true
})
const handleChange = (panel) => (event, isExpaneded) => setState(prev => ({ ...prev, [panel]: !isExpaneded }))
// render
<Accordion expaneded={state.panel1} onChange={handleChange('panel1')} />