繁体   English   中英

React Hooks useEffect 不会使用正确的状态

[英]React Hooks useEffect won't use the correct state

<Button
    onClick={() => {
        console.log('addedNodes', addedNodes)
        let credentials = //something...
        let nodes = [...addedNodes]
        console.log(addedNodes)
        setCurrentForm(
            {
                ...currentForm,
                credentials: credentials,
                nodes: [...addedNodes],
            }
        )
    }}
</Button>

我有一个按钮,它使用另一个状态addedNodes更新currentForm状态。 每当currentForm更新时,我都会使用useEffect控制台.记录currentForm

useEffect(() => {
        console.log('currentForm ,,,,,, ', currentForm)
        console.log('addedNodes ,,,,,, ', addedNodes)
    }, [currentForm]);

这将打印出正确的更新状态。

但是,当我尝试使用该状态添加 API 请求时,它会返回到更新之前的状态。

例如,当我将useEffect更新为

useEffect(() => {
        console.log('currentForm,,,,,, ', currentForm)
        console.log('addedNodes ,,,,,, ', addedNodes)
        console.log('RUNNING POST')
        setLoadingStatus('loading')

        let body = {
            form: currentForm,
        }

        intializeForms()
        let options = {
            headers: header,
            method: 'post',
            mode: 'cors',
            body: JSON.stringify(body),
        }
        console.log('options.body', options.body)

        const urls = ['...'];
        const fetchJson = url => fetch(url, options).then(res => res.json());
        Promise.all(urls.map(fetchJson))
            .then(([result]) => {
               ...
            })
            .catch(err => {
                setLoadingStatus('none')
                console.log(err)
            });

    }, [currentForm]);

console.log('options.body', options.body)打印出旧的currentForm

这很奇怪,因为console.log(currentForm)打印了预期的状态,但是当我实际将它用于 API 调用时,它又回到了原始表单。

我认为这是因为每次状态更新时都会调用这个useEffect ,但不确定。

请问有什么帮助吗?

有问题的代码片段

 let body = { form: currentForm, } intializeForms() // later bad body.form content

form到达参考currentFrom对象,然后currentFrom被覆盖在intializeForms() ...这样JSON.stringify(body)上的坏数据进行操作。

为什么 Kaca992 的解决方案不起作用?

 let body = { form: {...currentForm}, }

它应该从currentForm的元素/属性创建一个新对象。
可能它适用于currentForm某些部分, fe 用于nodes因为它们被正确(以不可变的方式 - 通过新实例)分配/传递:

 nodes: [...addedNodes],

可能其他currentForm元素是始终相同对象引用的副本,在更改时发生变异,而不是用新实例替换。

解决方案:

在这种情况下,在currentForm “消耗”(字符串化)之后调用intializeForms()就足够了 - let options = block。

其它好去处形式复位( intializeForms()调用)可以Promise.all(...解析功能( .then部分)。

initializeForms 有什么作用? 如果 currentForms 是引用类型,您可能会重置该值? 尝试像这样设置主体:

    let body = {
        form: {...currentForm},
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM