Material-UI v5.0 自定义Checkbox组件点击后state未更新问题
问题根因
状态不更新是父子组件Props传参名不匹配导致的:
- 父组件
CardNotes给自定义Checkbox传的属性是checked、onChange - 自定义Checkbox子组件里解构的属性名是
resolved、handleChange,完全接不到父组件传入的状态和变更回调
此时子组件内的MUI Checkbox处于非受控状态,会自己更新DOM勾选表现,但不会同步修改父组件的state,就会出现你看到的「DOM显示勾选、state一直为false」的现象。
除此之外你的代码还有几个影响功能和复用性的问题:
- 自定义子组件把label写死为
Resolvido,没有接收外部传入的label属性,不满足复用要求 - 未实现选中后自动禁用的需求
- 子组件声明时组件名拼写错误(写为
Chekbox漏了字母c),和引入名、文件名不匹配会触发导入报错 - 自定义组件内引入的MUI原生Checkbox名和自定义组件名重名,容易引发循环引用问题
修复方案
1. 修正自定义Checkbox组件
// Checkbox 组件 import React from 'react' import {FormControl , FormControlLabel} from '@mui/material'; // 重命名MUI原生Checkbox,避免和自定义组件名冲突 import MuiCheckbox from '@mui/material/Checkbox'; export default function Checkbox (props) { // 解构属性名和父组件传入的保持一致,新增disabled属性支持 const { checked, onChange, label, disabled } = props; return ( <FormControl> <FormControlLabel control={<MuiCheckbox checked={checked} color="primary" onChange={onChange} disabled={disabled} />} label={label} /> </FormControl> ) }
2. 修正父组件调用逻辑
父组件里删掉没被使用的冗余handleChange函数,调用自定义Checkbox时传入disabled属性,实现选中后自动禁用的效果:
// CardNotes Component 仅展示修改部分 export default function CardNotes({ note, handleDelete }){ const [checked, setChecked] = useState(false); const classes = useStyles(note) return( <div> <Card elevation={3} className={classes.test}> {/* 其余CardHeader、CardContent代码保持不变 */} <Box ml={2}> <Checkbox label="Resolvido" checked={checked} onChange={ (e) => setChecked(e.target.checked)} disabled={checked} // 选中状态下自动禁用 /> </Box> </Card> </div> ) }
复用说明
修复后的Checkbox组件可以直接在其他表单中复用,使用时只需要按需传入属性即可:
checked:绑定对应表单控制的选中状态onChange:传入状态更新函数,同步选中值label:传入复选框显示的文案- 可选传
disabled:控制禁用状态,不需要选中后禁用的场景可以不传该属性
内容的提问来源于stack exchange,提问作者Flavio Rocha 2018
相关产品推荐
相关产品推荐

