首页 > 解决方案 > React&Firebase,useState不更新,并将空数组传递给文档中的数组

问题描述

嗨,我希望你到目前为止过得愉快,我有一个问题想寻求帮助,如果你能提供帮助,请随时回答下面的问题。

所以我有一个名为“accounts”的 Firebase 集合,我想在我的文档中为该文档设置一个名为“basket”的数组。它工作正常,但有一个问题,那就是我有我的数组的 useState(我使用 map 将 useState 传递到篮子中)。首先传递一个空数组,这是useState的默认值,但我感到困惑的原因是我传递给useState的值,更新正常,并且有值,但是当我console.log或更新时我的数组使用了useState,它不包含数组,只有我第二次单击它时,它才被添加。

这是运行它的代码。

const [addBasket, setBasket] = useState([]);    

const addToBasketCollection = (name) => {
    setBasket([...addBasket, name.toLowerCase()])
    const user = auth.currentUser;
    console.log('Name: ' + name, '\nArray: ' + [...addBasket, name.toLowerCase()], '\nWhy does this not update: ', addBasket)
    db.collection('accounts').doc(user.uid).set(({
        basket: addBasket.map(doc => doc),
    }), { merge: true })
}


<button className="item-info__button" onClick={() => { addToBasketCollection(product.info.name) }}>Add</button>

注意: 上面的 console.log() 会在第一次单击按钮时返回:

Name: Mori 
Array: more 
Why does this not update:  []

在第二次单击按钮时,它会返回:

Name: Mori 
Array: more 
Why does this not update:  ["mori] // "mori" is the item's name that I added.

标签: reactjsfirebase

解决方案


addBasket是一个本地常量。它永远不会改变,这不是我们setBasket想要做的。设置状态是对重新渲染组件做出反应的指令。在该新渲染上,将使用新值创建一个新的本地常量。新渲染中的代码将能够看到新值;旧渲染中的代码不能。

如果旧代码需要使用新值,那么旧代码需要自己处理,而不是依赖addBasket变量。将新状态保存到变量应该是您的案例所需要的。如果要验证它是否使用新值呈现,请将 log 语句放在组件的主体中。

const [addBasket, setBasket] = useState([]);    

console.log('rendering with: ', addBasket);

const addToBasketCollection = (name) => {
    const newBasket = [...addBasket, name.toLowerCase()];
    setBasket(newBasket)
    const user = auth.currentUser;
    db.collection('accounts').doc(user.uid).set(({
        basket: newBasket.map(doc => doc),
    }), { merge: true })
}

推荐阅读