我试图在MUI扩展面板中添加一个材质UI开关。我已经在对象数组中维护了Switch的状态,并通过处理程序更改了状态。问题是,每当我单击开关时,状态都会正确更改,但直到我折叠并再次手动展开面板后,开关的动画才会显示。我调查了一个类似的问题,发现有些人使用了“ onClick”而不是“ onChange”,但不幸的是,同样的方法对我不起作用。
export default function ControlledExpansionPanels() {
const classes = useStyles();
const [expanded, setExpanded] = React.useState(false);
const initialValue = {
isPlanMigration: false,
restOfTheValues: "dummy Data"
};
const [value, setValue] = React.useState([initialValue]);
const handleplanMigrationChange = event => {
let updatedValue = value;
updatedValue.forEach((v, idx) => {
if (idx === Number(event.target.name.split("_")[1])) {
updatedValue[idx][event.target.name.split("_")[0]] =
event.target.checked;
}
});
setValue(updatedValue);
};
const addPanel = () => {
setValue(value.concat([initialValue]));
};
const handleExpansionPanelChange = panel => (event, isExpanded) => {
setExpanded(isExpanded ? panel : false);
};
return (
<div className={classes.root}>
{value.map((v, idx) => (
<ExpansionPanel
key={idx}
expanded={expanded === `panel_${idx}`}
onChange={handleExpansionPanelChange(`panel_${idx}`)}
>
<ExpansionPanelSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1bh-content"
id="panel1bh-header"
>
<Typography className={classes.heading}>
General settings
</Typography>
<Typography className={classes.secondaryHeading}>
I am an expansion panel
</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<FormControlLabel
control={
<Switch
label="Use Backenddiscover service"
checked={v.isPlanMigration}
onChange={handleplanMigrationChange}
color="primary"
name={`isPlanMigration_${idx}`}
inputProps={{ "aria-label": "primary checkbox" }}
/>
}
label="Plan migration is required"
/>
</ExpansionPanelDetails>
</ExpansionPanel>
))}
<IconButton
color="primary"
aria-label="Add API Config"
component="span"
onClick={addPanel}
>
<AddCircleIcon fontSize="large" />
</IconButton>
</div>
);
}
我尝试在扩展面板之外执行相同的操作,但似乎可行。
这里是sandbox的链接。 知道可能是什么问题吗?预先感谢!
答案 0 :(得分:1)
您正在通过将值数组复制到updatedValues数组来改变状态。因此是问题。
Your updated working codesandbox demo
解决方案-克隆阵列,然后设置状态
const handleplanMigrationChange = event => {
let updatedValue = [...value]; //<----- like this
let target = event.target;
updatedValue.forEach((v, idx) => {
if (idx === Number(target.name.split("_")[1])) {
updatedValue[idx][target.name.split("_")[0]] = target.checked;
}
});
setValue(updatedValue);
};
注意-如上所述,这是一个好习惯(也是安全的做法),它是复制event.target并将其传递给forEach回调,就像react event pooling
一样。