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

时间:2020-01-27 20:36:40

标签: javascript reactjs react-hooks

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

我有一个按钮,可以使用另一个状态currentForm更新addedNodes状态。 每当currentForm更新时,我都会使用currentForm来登录useEffect

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,但不是很确定。

有什么帮助吗?

2 个答案:

答案 0 :(得分:1)

问题代码片段

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

form获得对currentFrom对象的引用,然后currentFromintializeForms()中被覆盖...这样,JSON.stringify(body)对错误数据进行操作。

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

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

它应该从currentForm'元素/属性创建一个新对象。
可能对currentForm的某个部分有效,例如为nodes分配/通过了正确的(以不变的方式-通过新实例):

 nodes: [...addedNodes],

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

解决方案:

在这种情况下,只需在intializeForms()“消费”(字符串化)-currentForm块之后调用let options =

表单重置(intializeForms()调用)的其他好地方可以是Promise.all(...解析功能(.then部分)。

答案 1 :(得分:0)

initializeForms是做什么的?如果currentForms是引用类型,也许您要重置值?尝试像这样设置主体:

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