英文:
Why did the onChange handler delay the local state update in the ToggleButtonsGroup mui component?
问题
I have a problem with the ToggleButtonGroup component of the material-ui library, precisely in the onChange handler. At the beginning my code was more complex, I eliminated the problems one by one until I got this piece of code. But I can't understand the behavior of this code.
export default function ToggleButtons() {
// setting local state
const [values, setValues] = useState(() => []);
// toggle buttons handler
const onChangeHandler =(event: any, newValues: string[]) => {
setValues(newValues);
console.log('newValues', newValues);
console.log('state values', values);
};
return (
<ToggleButtonGroup
value={values}
onChange={onChangeHandler}
>
<ToggleButton value='first'>first</ToggleButton>
<ToggleButton value='second'>second</ToggleButton>
<ToggleButton value='third'>third</ToggleButton>
</ToggleButtonGroup>
);
}
Visually everything is perfect. But inside there is something that intrigues me.
It seems that the local state is always delayed. Did I write something wrong? If not then where is the problem?
英文:
I have a problem with the ToggleButtonGroup component of the material-ui library, precisely in the onChange handler. At the beginning my code was more complex, I eliminated the problems one by one until I got this piece of code. But I can't understand the behavior of this code.
export default function ToggleButtons() {
// setting local state
const [values, setValues] = useState(()=>[]);
// toggle buttons handler
const onChangeHandler =(event: any,newValues: string[]) => {
setValues(newValues);
console.log('newValues',newValues);
console.log('state values',values);
};
return (
<ToggleButtonGroup
value={values}
onChange={onChangeHandler}
>
<ToggleButton value='first' >first</ToggleButton>
<ToggleButton value='second' >second</ToggleButton>
<ToggleButton value='third' >third</ToggleButton>
</ToggleButtonGroup>
);
}
Visually everything is perfect. But inside there is something that intrigues me.
But please check my console##
- First button is checked
- First button is unchecked
- Second button is checked then the third
It seems that the local state is always delayed. Did I write something wrong? If not then where is the problem?
答案1
得分: 1
React 更新状态是异步的,因此您的 console.log 打印的是旧数据。
如果您使用React 开发工具来查看您的状态,它会正常工作:
英文:
React updates state asynchronously, so your console.log is printing stale data.
If you use React dev tools to see your state, it's working correctly:
答案2
得分: 0
尝试按照文档中的示例来创建 useState
语句。查看这里:
你的代码:
const [values, setValues] = useState(() => [])
他们的代码:
const [alignment, setAlignment] = React.useState<string | null>('left');
为什么你使用数组而不是简单的字符串?
看看他们的实现:
import FormatAlignCenterIcon from '@mui/icons-material/FormatAlignCenter';
import FormatAlignRightIcon from '@mui/icons-material/FormatAlignRight';
import FormatAlignJustifyIcon from '@mui/icons-material/FormatAlignJustify';
import ToggleButton from '@mui/material/ToggleButton';
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
export default function ToggleButtons() {
const [alignment, setAlignment] = React.useState<string | null>('left');
const handleAlignment = (
event: React.MouseEvent<HTMLElement>,
newAlignment: string | null,
) => {
setAlignment(newAlignment);
};
return (
<ToggleButtonGroup
value={alignment}
exclusive
onChange={handleAlignment}
aria-label="text alignment"
>
<ToggleButton value="left" aria-label="left aligned">
<FormatAlignLeftIcon />
</ToggleButton>
<ToggleButton value="center" aria-label="centered">
<FormatAlignCenterIcon />
</ToggleButton>
<ToggleButton value="right" aria-label="right aligned">
<FormatAlignRightIcon />
</ToggleButton>
<ToggleButton value="justify" aria-label="justified" disabled>
<FormatAlignJustifyIcon />
</ToggleButton>
</ToggleButtonGroup>
);
}
英文:
try to make useState statement exactly as in documentation.
https://mui.com/material-ui/react-toggle-button/
take a look =>
you did :
const [values, setValues] = useState(()=>[])
they did:
const [alignment, setAlignment] = React.useState<string | null>('left');
why do you use array instead of just simple string?
look at their implementation:
import FormatAlignCenterIcon from '@mui/icons-material/FormatAlignCenter';
import FormatAlignRightIcon from '@mui/icons-material/FormatAlignRight';
import FormatAlignJustifyIcon from '@mui/icons-material/FormatAlignJustify';
import ToggleButton from '@mui/material/ToggleButton';
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
export default function ToggleButtons() {
const [alignment, setAlignment] = React.useState<string | null>('left');
const handleAlignment = (
event: React.MouseEvent<HTMLElement>,
newAlignment: string | null,
) => {
setAlignment(newAlignment);
};
return (
<ToggleButtonGroup
value={alignment}
exclusive
onChange={handleAlignment}
aria-label="text alignment"
>
<ToggleButton value="left" aria-label="left aligned">
<FormatAlignLeftIcon />
</ToggleButton>
<ToggleButton value="center" aria-label="centered">
<FormatAlignCenterIcon />
</ToggleButton>
<ToggleButton value="right" aria-label="right aligned">
<FormatAlignRightIcon />
</ToggleButton>
<ToggleButton value="justify" aria-label="justified" disabled>
<FormatAlignJustifyIcon />
</ToggleButton>
</ToggleButtonGroup>
);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论