Material UI Checkbox 首次点击出现重复值、状态更新异常问题排查
问题根源
- React状态更新为异步批量执行,调用
setWaterChecked(event.target.checked)后,当前handleChangeWater作用域内读取的waterChecked仍是更新前的旧值,所以判断逻辑用的是历史状态,才会出现前两次点击结果不符合预期的问题。 - Material UI的
Checkbox受控组件属性使用错误:受控模式下需用标准checked属性绑定状态,你自定义的waterChecked属性组件无法识别,同时受控组件不需要配置defaultChecked,二者共存会导致受控/非受控模式冲突。
修复方案
直接用事件对象返回的最新勾选值做判断,不要依赖旧状态,同时修正组件属性:
const [waterChecked, setWaterChecked] = React.useState(true); const [data, setData] = useState(null); const handleChangeWater = (event) => { // 先拿到最新的勾选状态再处理所有逻辑 const newChecked = event.target.checked; setWaterChecked(newChecked); if (newChecked) { setData([1, 2, 3, 4]) } else { setData([]) } }; // 渲染部分修正Checkbox属性 <ul> <Checkbox checked={waterChecked} // 受控组件必须用标准checked属性绑定状态 onChange={handleChangeWater} inputProps={{ 'aria-label': 'controlled' }} /> Water </ul>
如果需要严格在waterChecked状态更新完成后再修改data,也可以用useEffect监听状态变化实现:
const [waterChecked, setWaterChecked] = React.useState(true); const [data, setData] = useState(null); // 监听waterChecked变化后自动同步data useEffect(() => { setData(waterChecked ? [1,2,3,4] : []) }, [waterChecked]) const handleChangeWater = (event) => { setWaterChecked(event.target.checked); }; // 渲染部分和上面一致 <ul> <Checkbox checked={waterChecked} onChange={handleChangeWater} inputProps={{ 'aria-label': 'controlled' }} /> Water </ul>
内容的提问来源于stack exchange,提问作者Jamie Huff
相关产品推荐
相关产品推荐

