【问题标题】:Why is my React useState updating my context asynchronously? [duplicate]为什么我的 React useState 会异步更新我的上下文? [复制]
【发布时间】:2019-11-10 07:01:10
【问题描述】:

我有一个创建三个单选按钮的组件。选择一个应该更新我在别处拥有的上下文存储。

我的状态是这样的:

const styles = {
    font: {
        size: {
            value: '22',
            unit: 'px'
        },
        weight: 'bold',
        color: '#663300',
        family: 'arial',
        align: 'center'
    }
};

我这样存储我的状态:

const myContext = useEmailContext();
const { ...styling } = styles;
const [style, setStyle] = useState({ styling });

然后我的组件触发函数onChange:

return (
    <RadioButtonGroup
        onChange={(event) => {
            setIsChecked({ checked: event.target.value });
            setStyle({ ...styling,  font: { ...styling.font, align: event.target.value } });
            console.log(style);
            myContext.setStyles(style);
        }}
    />

当我点击一个按钮时,函数会触发,但 console.log 显示的是 previous 状态,而不是新更新的状态。同样,我的上下文也会落后一步更新。

这是怎么回事?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    状态更新与 useState hooks updater 是异步的。您可以在这篇文章中了解更多信息:

    useState set method not reflecting change immediately

    但是你可以像解决上下文值更新

    return (
        <RadioButtonGroup
            onChange={(event) => {
                setIsChecked({ checked: event.target.value });
                const newStyle = { ...styling,  font: { ...styling.font, align: event.target.value } }
                setStyle(newStyle);
                myContext.setStyles(newStyle);
            }}
        />
    )
    

    或者你可以使用 useEffect 钩子更新上下文值

    useEffect(() => {
         myContext.setStyles(styling);
    }, [styling]);
    
    return (
        <RadioButtonGroup
            onChange={(event) => {
                setIsChecked({ checked: event.target.value });
                setStyle({ ...styling,  font: { ...styling.font, align: event.target.value } });
            }}
        />
    )
    

    【讨论】:

    • 也许处理它的正确位置在 useEffect() ?因此,无论何时何地样式发生变化,它都会传播到上下文,而无需在每个方法中显式设置上下文。
    • @MosèRaguzzini 这是一种方法,但由于相同的样式要传递给上下文和状态,我认为我们不需要 useEffect。上述解决方案将正常工作:-)
    • 嗨,伙计,我知道这“行得通”,但我只是按照您答案中的链接进行操作,它说明了同样的事情。尽管您的解决方案有效,但这不是最终或最干净的解决方案。
    【解决方案2】:

    Shubham Khatri 的回答应该可以按预期工作,但最干净的解决方案是使用 useEffect() 钩子:

    useEffect(() => {
        // this is the place to update your context, and it will work every time style is updated, everytime, everywhere.
    }, [style]);
    

    这将阻止您在发生更改时手动更新上下文。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 2019-10-19
      • 2021-07-14
      • 2020-11-25
      相关资源
      最近更新 更多