【问题标题】:React Hooks useEffect won't use the correct stateReact Hooks useEffect 不会使用正确的状态
【发布时间】:2020-01-27 20:36:40
【问题描述】:
<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,但不确定。

有什么帮助吗?

【问题讨论】:

  • useEffect 回调将在每次currentForm 值更改时运行,而不是在任何其他值更改时运行
  • @BillMetcalf 我要问的是,useEffect 得到了正确的 currentForm,但没有将正确的东西传递给身体
  • 注释掉initializeForms()或移至.then
  • @xadm then 如何在 useEffect 中工作?是不是类似于... [currentForm]).then( ... )
  • no ... 进入 Promise .then .... 但首先测试删除此调用

标签: javascript reactjs react-hooks


【解决方案1】:

有问题的代码片段

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

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

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

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

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

 nodes: [...addedNodes],

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

解决方案:

在这种情况下,在 currentForm "消费" (stringify) - let options = 块之后调用 intializeForms() 就足够了。

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

【讨论】:

  • 很好的答案。谢谢!
【解决方案2】:

initializeForms 有什么作用?如果 currentForms 是一个引用类型,也许你重置了这个值?尝试像这样设置身体:

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

【讨论】:

  • 谢谢,但是没有用。导致同样的问题。
  • 如果 intializeForms 更改 currentForm,您还需要一种机制来摆脱下一个 useEffect。在 useEffect 的顶部进行一些检查(例如状态是否正在加载或 currentForm 是否为空)。
猜你喜欢
  • 2019-07-22
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 2020-11-28
  • 2019-08-04
  • 2019-07-07
  • 2020-07-15
  • 2020-01-06
相关资源
最近更新 更多