onChange处理程序为什么延迟了ToggleButtonsGroup MUI组件中的本地状态更新?

huangapple go评论110阅读模式
英文:

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.

  1. export default function ToggleButtons() {
  2. // setting local state
  3. const [values, setValues] = useState(() => []);
  4. // toggle buttons handler
  5. const onChangeHandler =(event: any, newValues: string[]) => {
  6. setValues(newValues);
  7. console.log('newValues', newValues);
  8. console.log('state values', values);
  9. };
  10. return (
  11. <ToggleButtonGroup
  12. value={values}
  13. onChange={onChangeHandler}
  14. >
  15. <ToggleButton value='first'>first</ToggleButton>
  16. <ToggleButton value='second'>second</ToggleButton>
  17. <ToggleButton value='third'>third</ToggleButton>
  18. </ToggleButtonGroup>
  19. );
  20. }

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.

  1. export default function ToggleButtons() {
  2. // setting local state
  3. const [values, setValues] = useState(()=&gt;[]);
  4. // toggle buttons handler
  5. const onChangeHandler =(event: any,newValues: string[]) =&gt; {
  6. setValues(newValues);
  7. console.log(&#39;newValues&#39;,newValues);
  8. console.log(&#39;state values&#39;,values);
  9. };
  10. return (
  11. &lt;ToggleButtonGroup
  12. value={values}
  13. onChange={onChangeHandler}
  14. &gt;
  15. &lt;ToggleButton value=&#39;first&#39; &gt;first&lt;/ToggleButton&gt;
  16. &lt;ToggleButton value=&#39;second&#39; &gt;second&lt;/ToggleButton&gt;
  17. &lt;ToggleButton value=&#39;third&#39; &gt;third&lt;/ToggleButton&gt;
  18. &lt;/ToggleButtonGroup&gt;
  19. );
  20. }

Visually everything is perfect. But inside there is something that intrigues me.

onChange处理程序为什么延迟了ToggleButtonsGroup MUI组件中的本地状态更新?

But please check my console##

  • First button is checked

onChange处理程序为什么延迟了ToggleButtonsGroup MUI组件中的本地状态更新?

  • First button is unchecked

onChange处理程序为什么延迟了ToggleButtonsGroup MUI组件中的本地状态更新?

  • Second button is checked then the third

onChange处理程序为什么延迟了ToggleButtonsGroup MUI组件中的本地状态更新?

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 开发工具来查看您的状态,它会正常工作:

onChange处理程序为什么延迟了ToggleButtonsGroup MUI组件中的本地状态更新?

onChange处理程序为什么延迟了ToggleButtonsGroup MUI组件中的本地状态更新?

英文:

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:

onChange处理程序为什么延迟了ToggleButtonsGroup MUI组件中的本地状态更新?

onChange处理程序为什么延迟了ToggleButtonsGroup MUI组件中的本地状态更新?

答案2

得分: 0

尝试按照文档中的示例来创建 useState 语句。查看这里:
你的代码:
const [values, setValues] = useState(() => [])
他们的代码:

  1. const [alignment, setAlignment] = React.useState<string | null>('left');

为什么你使用数组而不是简单的字符串?
看看他们的实现:

  1. import FormatAlignCenterIcon from '@mui/icons-material/FormatAlignCenter';
  2. import FormatAlignRightIcon from '@mui/icons-material/FormatAlignRight';
  3. import FormatAlignJustifyIcon from '@mui/icons-material/FormatAlignJustify';
  4. import ToggleButton from '@mui/material/ToggleButton';
  5. import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
  6. export default function ToggleButtons() {
  7. const [alignment, setAlignment] = React.useState<string | null>('left');
  8. const handleAlignment = (
  9. event: React.MouseEvent<HTMLElement>,
  10. newAlignment: string | null,
  11. ) => {
  12. setAlignment(newAlignment);
  13. };
  14. return (
  15. <ToggleButtonGroup
  16. value={alignment}
  17. exclusive
  18. onChange={handleAlignment}
  19. aria-label="text alignment"
  20. >
  21. <ToggleButton value="left" aria-label="left aligned">
  22. <FormatAlignLeftIcon />
  23. </ToggleButton>
  24. <ToggleButton value="center" aria-label="centered">
  25. <FormatAlignCenterIcon />
  26. </ToggleButton>
  27. <ToggleButton value="right" aria-label="right aligned">
  28. <FormatAlignRightIcon />
  29. </ToggleButton>
  30. <ToggleButton value="justify" aria-label="justified" disabled>
  31. <FormatAlignJustifyIcon />
  32. </ToggleButton>
  33. </ToggleButtonGroup>
  34. );
  35. }
英文:

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(()=&gt;[])
they did:

  1. const [alignment, setAlignment] = React.useState&lt;string | null&gt;(&#39;left&#39;);

why do you use array instead of just simple string?
look at their implementation:

  1. import FormatAlignCenterIcon from &#39;@mui/icons-material/FormatAlignCenter&#39;;
  2. import FormatAlignRightIcon from &#39;@mui/icons-material/FormatAlignRight&#39;;
  3. import FormatAlignJustifyIcon from &#39;@mui/icons-material/FormatAlignJustify&#39;;
  4. import ToggleButton from &#39;@mui/material/ToggleButton&#39;;
  5. import ToggleButtonGroup from &#39;@mui/material/ToggleButtonGroup&#39;;
  6. export default function ToggleButtons() {
  7. const [alignment, setAlignment] = React.useState&lt;string | null&gt;(&#39;left&#39;);
  8. const handleAlignment = (
  9. event: React.MouseEvent&lt;HTMLElement&gt;,
  10. newAlignment: string | null,
  11. ) =&gt; {
  12. setAlignment(newAlignment);
  13. };
  14. return (
  15. &lt;ToggleButtonGroup
  16. value={alignment}
  17. exclusive
  18. onChange={handleAlignment}
  19. aria-label=&quot;text alignment&quot;
  20. &gt;
  21. &lt;ToggleButton value=&quot;left&quot; aria-label=&quot;left aligned&quot;&gt;
  22. &lt;FormatAlignLeftIcon /&gt;
  23. &lt;/ToggleButton&gt;
  24. &lt;ToggleButton value=&quot;center&quot; aria-label=&quot;centered&quot;&gt;
  25. &lt;FormatAlignCenterIcon /&gt;
  26. &lt;/ToggleButton&gt;
  27. &lt;ToggleButton value=&quot;right&quot; aria-label=&quot;right aligned&quot;&gt;
  28. &lt;FormatAlignRightIcon /&gt;
  29. &lt;/ToggleButton&gt;
  30. &lt;ToggleButton value=&quot;justify&quot; aria-label=&quot;justified&quot; disabled&gt;
  31. &lt;FormatAlignJustifyIcon /&gt;
  32. &lt;/ToggleButton&gt;
  33. &lt;/ToggleButtonGroup&gt;
  34. );
  35. }

huangapple
  • 本文由 发表于 2023年2月6日 20:16:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75361205.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定