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

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

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

    // toggle buttons handler
    const onChangeHandler =(event: any,newValues: string[]) =&gt; {
        setValues(newValues);
        console.log(&#39;newValues&#39;,newValues);
        console.log(&#39;state values&#39;,values);
      };

    
    return (
        &lt;ToggleButtonGroup
            value={values}
            onChange={onChangeHandler}
        &gt;
            &lt;ToggleButton value=&#39;first&#39; &gt;first&lt;/ToggleButton&gt;
            &lt;ToggleButton value=&#39;second&#39; &gt;second&lt;/ToggleButton&gt;
            &lt;ToggleButton value=&#39;third&#39; &gt;third&lt;/ToggleButton&gt;
        &lt;/ToggleButtonGroup&gt;
    );
}

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(() => [])
他们的代码:

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

 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:

import FormatAlignCenterIcon from &#39;@mui/icons-material/FormatAlignCenter&#39;;
import FormatAlignRightIcon from &#39;@mui/icons-material/FormatAlignRight&#39;;
import FormatAlignJustifyIcon from &#39;@mui/icons-material/FormatAlignJustify&#39;;
import ToggleButton from &#39;@mui/material/ToggleButton&#39;;
import ToggleButtonGroup from &#39;@mui/material/ToggleButtonGroup&#39;;
export default function ToggleButtons() {
const [alignment, setAlignment] = React.useState&lt;string | null&gt;(&#39;left&#39;);
const handleAlignment = (
event: React.MouseEvent&lt;HTMLElement&gt;,
newAlignment: string | null,
) =&gt; {
setAlignment(newAlignment);
};
return (
&lt;ToggleButtonGroup
value={alignment}
exclusive
onChange={handleAlignment}
aria-label=&quot;text alignment&quot;
&gt;
&lt;ToggleButton value=&quot;left&quot; aria-label=&quot;left aligned&quot;&gt;
&lt;FormatAlignLeftIcon /&gt;
&lt;/ToggleButton&gt;
&lt;ToggleButton value=&quot;center&quot; aria-label=&quot;centered&quot;&gt;
&lt;FormatAlignCenterIcon /&gt;
&lt;/ToggleButton&gt;
&lt;ToggleButton value=&quot;right&quot; aria-label=&quot;right aligned&quot;&gt;
&lt;FormatAlignRightIcon /&gt;
&lt;/ToggleButton&gt;
&lt;ToggleButton value=&quot;justify&quot; aria-label=&quot;justified&quot; disabled&gt;
&lt;FormatAlignJustifyIcon /&gt;
&lt;/ToggleButton&gt;
&lt;/ToggleButtonGroup&gt;
);
}

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:

确定