Javascript 为什么我的状态是异步更新我的上下文?

Javascript 为什么我的状态是异步更新我的上下文?,javascript,reactjs,Javascript,Reactjs,我有一个组件,可以创建三个单选按钮。Cicking one应该更新我在别处的上下文存储 我的状态是这样的: const styles = { font: { size: { value: '22', unit: 'px' }, weight: 'bold', color: '#663300', family: 'arial', align: 'c

我有一个组件,可以创建三个单选按钮。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 });
我将状态存储为:

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);
        }}
    />
返回(
{
setIsChecked({选中:event.target.value});
setStyle({…样式,字体:{…样式.font,align:event.target.value}});
console.log(风格);
myContext.setStyles(样式);
}}
/>
当我点击一个按钮时,函数启动,但console.log显示的是以前的状态,而不是新更新的状态。同样,我的上下文也会落后一步更新


这里发生了什么?

状态更新与useState hooks updater是异步的。您可以在这篇文章中阅读更多关于它的内容:

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

return (
    <RadioButtonGroup
        onChange={(event) => {
            setIsChecked({ checked: event.target.value });
            const newStyle = { ...styling,  font: { ...styling.font, align: event.target.value } }
            setStyle(newStyle);
            myContext.setStyles(newStyle);
        }}
    />
)
返回(
{
setIsChecked({选中:event.target.value});
const newStyle={…样式,字体:{…样式.font,align:event.target.value}
设置样式(新闻样式);
myContext.setStyles(newStyle);
}}
/>
)
或者您可以使用useffect钩子更新上下文值,如

useEffect(() => {
     myContext.setStyles(styling);
}, [styling]);

return (
    <RadioButtonGroup
        onChange={(event) => {
            setIsChecked({ checked: event.target.value });
            setStyle({ ...styling,  font: { ...styling.font, align: event.target.value } });
        }}
    />
)
useffect(()=>{
myContext.setStyles(样式);
},[造型];
返回(
{
setIsChecked({选中:event.target.value});
setStyle({…样式,字体:{…样式.font,align:event.target.value}});
}}
/>
)

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


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

可能正确的处理位置是useEffect()?因此,无论何时何地样式发生更改,它都会传播到上下文,而不会在每个方法中对上下文进行显式设置。@MosèRaguzzini这是一种方法,但由于相同的样式将传递到上下文和状态,我认为我们不需要useEffect。上述解决方案将正常工作:-)Hi mate,我知道这“很有效”,但我只是按照你答案中的链接,它说明了同样的事情。虽然您的解决方案有效,但这不是最终的或最干净的解决方案。