代码之家  ›  专栏  ›  技术社区  ›  Dawn17

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

  •  0
  • Dawn17  · 技术社区  · 6 年前
    <Button
        onClick={() => {
            console.log('addedNodes', addedNodes)
            let credentials = //something...
            let nodes = [...addedNodes]
            console.log(addedNodes)
            setCurrentForm(
                {
                    ...currentForm,
                    credentials: credentials,
                    nodes: [...addedNodes],
                }
            )
        }}
    </Button>
    

    我有一个按钮可以更新 currentForm 使用另一个州 addedNodes . 每当 当前表格 更新了,我安慰 当前表格 使用 useEffect .

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

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

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

    例如,当我更新我的 使用效果

    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) 打印出旧的 当前表格 .

    这很奇怪,因为 console.log(currentForm) 打印期望的状态,但当我实际将其用于API调用时,它会返回到原始形式。

    我想这是因为 使用效果 每次状态更新时都会被调用,但并不确定。

    有什么帮助吗?

    0 回复  |  直到 6 年前
        1
  •  1
  •   xadm    6 年前

    有问题的代码片段

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

    form 获取一个引用 currentFrom 对象然后 current从 被覆盖在 intializeForms() …这边 JSON.stringify(body) 基于不良数据进行操作。

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

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

    它应该从以下对象创建一个新对象 currentForm '元素/属性。
    也许它在某些方面奏效了 当前表格 ,例如for nodes 因为它们是通过新实例以不可变的方式正确分配/传递的:

     nodes: [...addedNodes],
    

    可能其他 当前表格 元素是以下内容的副本 总是相同的对象引用 ,在更改时发生突变,不被新实例替换。

    解决方案:

    在这种情况下,打个电话就够了 初始化表单() 刚刚之后 当前表格 “消费”(字符串化)- let options = 块。

    其他用于表单重置的好地方( 初始化表单() 呼叫)可以 Promise.all(... 解析函数( .then 部分)。

        2
  •  0
  •   Kaca992    6 年前

    initializeForms做什么?如果currentForms是引用类型,您是否可以重置该值?试着这样设置身体:

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