当前位置: 首页 > 知识库问答 >
问题:

为什么我的状态是异步更新我的上下文?[副本]

祝宾白
2023-03-14

我有一个组件,可以创建三个单选按钮。Cicking one应该更新我在别处的上下文存储。

我的状态是这样的:

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将显示以前的状态,而不是新更新的状态。同样,我的上下文也会落后一步更新。

这到底是怎么回事?

共有2个答案

燕翼
2023-03-14

状态更新与useState钩子更新程序是异步的。你可以在这篇文章中阅读更多关于它的信息:

useState集合方法不能立即反映更改

但是,您可以像这样解决上下文值更新问题

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(() => {
     myContext.setStyles(styling);
}, [styling]);

return (
    <RadioButtonGroup
        onChange={(event) => {
            setIsChecked({ checked: event.target.value });
            setStyle({ ...styling,  font: { ...styling.font, align: event.target.value } });
        }}
    />
)
公孙棋
2023-03-14

Shubham Khatri的回答应该如预期的那样有效,但最干净的解决方案是使用useEffect()挂钩:

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

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

 类似资料:
  • 我通过使用map函数迭代来显示我的状态,这是一个数组。此外,我有一个按钮,在点击反转数组。 我认为我想做什么是相当明显的。但这对我不起作用,我不知道为什么。我必须单击两次来完成第一次还原,出现了奇怪的情况,即呈现的数组和Chrome中React开发工具在组件状态中显示的数组不匹配。 我无法解释这种行为。我开始认为这与我从道具中获得阵列有关,但我真的不知道。有什么想法吗?

  • 我想从一个长期运行的方法状态更新。通常我会使用dispatcher回发到UI线程,但我对使用async Await很好奇。 为了简单起见: 但这是Fugly。此外,如果您去掉async和await关键字并将其替换为task.waitall,它仍将按预期执行。 注意:如果您想知道为什么我使用thread.sleep而不是task.delay,我实际上也在Silverlight中测试了这一点,异步等待

  • 各位早上好,, 我刚完成React的培训,我想做一个项目来练习。首先,我只是在firebase数据库中发布数据。然后,我想使用钩子(useState和useEffect)获取数据并将其显示在react组件中。 问题是,在使用axios获取数据后,我最终陷入了经典的无限循环陷阱,但我不知道如何使用依赖性来阻止它。 请查找以下代码: 当我使用控制台日志类型时,数据是正确的。但当我控制台记录fetche

  • 问题内容: 网上散布着许多页面,这些页面以不同的细节描述了POSIX AIO设备。它们都不是最新的。目前尚不清楚他们在描述什么。例如,这里的Linux内核异步I / O支持 的“官方”(?)网站表示套接字不起作用,但是Ubuntu 8.04.1工作站上的“ aio.h”手册页似乎都暗示着它适用于任意文件描述符。然后还有另一个项目似乎可以在库层工作,甚至需要更少的文档。 我想知道: POSIX AI

  • 问题内容: 我有如下代码: 但是,不是在每次调用setText时在循环的每次迭代后更新文本区域,而是仅在完成所有任务运行后才更新文本。为什么会发生这种情况,我该如何解决? 问题答案: 您可能正在使用Swing线程,该线程正在等待代码执行才能更新UI。尝试为该循环使用单独的线程。

  • choice5是一个JComboBox 从choice5中选择项目时 被称为(编辑:对于我可以选择的每个项目,我可能有一个不同的jtable我想要显示) 编辑(SSCCE): MyTableModel