首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React setState阵列问题

React setState阵列问题
EN

Stack Overflow用户
提问于 2020-10-22 22:11:01
回答 1查看 60关注 0票数 0

我有下面的javascript代码:

代码语言:javascript
复制
const getProducts = () => {
        votationRef
            .child(moment().format('yyyy-MM-DD'))
            .once('value').then((snapshot) => {
                try {
                    var productsId = snapshot.val();
                    productsId.map((item) => {
                        productsRef
                            .child(item)
                            .once('value')
                            .then((snapshot) => {
                                setProducts([...products, snapshot.val()]);
                            })
                    })
                } catch (e) {
                    console.log('ERROR', e.message)
                }
            })
    }

简而言之,在DOM完成加载之前,使用useEffect钩子调用函数getProducts

此函数的任务是检索存储在我的Firebase RT DB上的每个产品的详细信息(按每个productsId),并将它们放入一个状态数组(setProducts)中。

最终的products数组结果在我的JSX中简单地显示为“段落列表”。代码如下:

代码语言:javascript
复制
products.map((item) => {
    return <p>{item.name}</p>
})

谁能给我解释一下,为什么我的React状态products,在上述过程的末尾,只包含我的firebase "products“文档节点中最后一个产品的详细信息?

目前,我的firebase "products“文档节点包含以下数据:

代码语言:javascript
复制
"products" : {
    "-MK-CnXnTYbyYm5eyYBK" : {
      "coverImg" : "https://firebasestorage.googleapis.com/v0/b/onebidup.appspot.com/o/images%2FcoverImages%2F32a01e12-e7a2-44df-ac62-5d5eac00d031.jpg?alt=media&token=7b9b8304-c0b1-4123-85fd-b0fe4096d3d0",
      "description" : "Audio che riempie la stanza - I cinque altoparlanti offrono bassi potenti, medi dinamici e alti nitidi",
      "maxVote" : 5,
      "name" : "Echo Studio - Altoparlante intelligente",
      "price" : "189.99"
    },
    "-MKFOYfuAdK8Fo4l-aiV" : {
      "coverImg" : "https://firebasestorage.googleapis.com/v0/b/onebidup.appspot.com/o/images%2FcoverImages%2F8e1edf42-562b-4a05-8180-b320968b1024.jpg?alt=media&token=ffad077c-014c-4a60-aab0-edb2cbe526f5",
      "description" : "La serie Q64 è una variante di colore silver della serie Q60 a cui aggiunge il telecomando Premium Metal One Remote e la tecnologia di controllo dell’immagine Ultimate UHD Dimming",
      "name" : "Samsung QE55Q64RATXZT Serie Q64R QLED Smart TV 55\", Ultra HD 4K, Wi-Fi, Silver, 2019",
      "price" : "669"
    },
    "-MKFOsBlMmFS5wnBk8jr" : {
      "coverImg" : "https://firebasestorage.googleapis.com/v0/b/onebidup.appspot.com/o/images%2FcoverImages%2Fa7247e86-b745-4806-8e93-1de733e4f698.jpg?alt=media&token=4b0adf1c-9a90-4da7-9c43-5db40d80ee76",
      "description" : "Splendidamente progettato e costruito per durare - elegante, pratico e affidabile",
      "name" : "Segway-Ninebot ES4 Monopattino Elettrico",
      "price" : "773"
    },
    "-MKFPAewl96EKp3noj2J" : {
      "coverImg" : "https://firebasestorage.googleapis.com/v0/b/onebidup.appspot.com/o/images%2FcoverImages%2F1943a11f-d1ee-4188-9aa9-af0d42466d11.jpg?alt=media&token=f6e1f9ae-7632-406e-acde-5554c45d5ee4",
      "description" : "Sony PS4 PRO PlayStation Gamma Chassis + PS Live Card 20€, 4K HDR, 1 TB [Esclusiva Amazon.it]",
      "name" : "Sony PS4 PRO PlayStation",
      "price" : "419"
    },
    "-MKFPY6pWSPGUfTGIUuH" : {
      "coverImg" : "https://firebasestorage.googleapis.com/v0/b/onebidup.appspot.com/o/images%2FcoverImages%2F0fccd324-e03e-4680-8553-688dd1be25bc.jpg?alt=media&token=c695e0af-d2d2-448e-9747-1aaa6910197f",
      "description" : "iRobot Roomba 981 Robot aspirapolvere WiFi, Power-Lifting, 2 spazzole in gomma multi-superficie, Adatto per peli, Tecnologia Dirt Detect, pulizia a 3 fasi, programmabile con app, Compatibile Alexa",
      "name" : "iRobot Roomba 981",
      "price" : "538.80"
    }
  }
EN

回答 1

Stack Overflow用户

发布于 2020-10-22 22:21:03

问题是products是一个空数组,即使在您调用:

代码语言:javascript
复制
setProducts([...products, snapshot.val()])

要在前一个值的基础上构建,您必须使用回调变量:

代码语言:javascript
复制
setProducts(products => [...products, snapshot.val()])

主要问题是setProducts会在下一次渲染时更新products。它不会影响products的当前值。通过使用回调,新值被传入,然后就可以使用了。

此行为在useState文档中进行了描述:

函数更新

如果使用以前的状态计算新状态,则可以将函数传递给setState。该函数将接收前一个值,并返回一个更新值。下面是使用这两种形式的setState的计数器组件的示例:

函数计数器({initialCount}){ const count,setCount = useState(initialCount);return (按钮计数:{ <> }<按钮onClick={() => setCount(initialCount)}>Reset <按钮onClick={() => setCount(prevCount => prevCount - 1)}>- <按钮onClick={() => setCount(prevCount +1)} );}

“+”和“-”按钮使用函数形式,因为更新后的值基于先前的值。但是“Reset”按钮使用的是标准形式,因为它总是将计数设置回初始值。

如果您的更新函数返回与当前状态完全相同的值,则将完全跳过后续的重新渲染。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64484102

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档