我有下面的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中简单地显示为“段落列表”。代码如下:
products.map((item) => {
return <p>{item.name}</p>
})谁能给我解释一下,为什么我的React状态products,在上述过程的末尾,只包含我的firebase "products“文档节点中最后一个产品的详细信息?
目前,我的firebase "products“文档节点包含以下数据:
"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"
}
}发布于 2020-10-22 22:21:03
问题是products是一个空数组,即使在您调用:
setProducts([...products, snapshot.val()])要在前一个值的基础上构建,您必须使用回调变量:
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”按钮使用的是标准形式,因为它总是将计数设置回初始值。
如果您的更新函数返回与当前状态完全相同的值,则将完全跳过后续的重新渲染。
https://stackoverflow.com/questions/64484102
复制相似问题