reactjs - Firestore onSnapshot 更新并将数组添加到 DOM 而不是仅更新
问题描述
我有来自 Firestore 的数据,我正在映射到 DOM,然后更新客户端。当数据按照我想要的方式更新时,每次触发事件时,都会将另一个更新的数组添加到 DOM 中。
我认为问题在于单击事件的设置方式,但我不确定如何在阵列上应用我的客户端操作。
这是我的设置和点击事件
function App() {
const [heroesArr, setHeroesArr] = useState([]);
const db = firebase.firestore();
const onFetch = () => {
const newHeroes = [];
db.collection("characterOptions").onSnapshot(coll => {
coll.forEach(doc => {
const { Name, uidDownvoted, uidUpvoted, votes } = doc.data();
newHeroes.push({
key: doc.id,
doc,
Name,
uidDownvoted,
uidUpvoted,
votes
});
});
setHeroesArr(newHeroes);
});
};
const onUpVote = i => {
const collRef = db.collection("characterOptions");
setHeroesArr(heroesArr =>
heroesArr.map((item, o) => {
if (i === o && !item.uidDownvoted && !item.uidUpvoted) {
collRef.doc(item.key).update({
votes: firebase.firestore.FieldValue.increment(1),
uidUpvoted: true
});
} else if (i === o && !item.uidDownvoted && item.uidUpvoted) {
collRef.doc(item.key).update({
votes: firebase.firestore.FieldValue.increment(-1),
uidUpvoted: false
});
} else if (i === o && item.uidDownvoted && !item.uidUpvoted) {
collRef.doc(item.key).update({
votes: firebase.firestore.FieldValue.increment(2),
uidUpvoted: true,
uidDownvoted: false
});
}
return item;
})
);
};
这是标记
return (
<div className="App">
<button onClick={onFetch}>click</button>
{heroesArr.map((item, i) => (
<div key={item.key}>
<p>{item.Name}</p>
<p>{item.votes}</p>
{item.uidDownvoted && <p>this has been downvoted</p>}
{item.uidUpvoted && <p>this has been upvoted</p>}
<button onClick={() => onUpVote(i)}>Upvote</button>
</div>
))}
</div>
);
我显然只是希望数组更新,而不是每次触发点击事件时创建一个额外的更新副本。
解决方案
你有两个选择:
- 始终清除数组
- 执行增量更新
由于第一个选项是最简单的,我将向您展示其代码。
现在,你声明你的newHeroes
外部onSnapshot
,即使你只在里面使用它。这意味着每次循环时,coll.forEach()
您都会将所有元素添加到 中newHeroes
,包括您之前阅读过的元素。
最简单的选择是newHeroes
在回调内部声明,以便每次回调运行时它都开始为空。
db.collection("characterOptions").onSnapshot(coll => {
const newHeroes = [];
coll.forEach(doc => {
const { Name, uidDownvoted, uidUpvoted, votes } = doc.data();
newHeroes.push({
key: doc.id,
doc,
Name,
uidDownvoted,
uidUpvoted,
votes
});
});
setHeroesArr(newHeroes);
});
另一种方法是使用 Firestore 为您提供的有关哪些文档是新文档、哪些文档已更新等的信息。要获取此信息,您需要遍历coll.documentChanges
. 有关这方面的示例,请参阅有关快照之间视图更改的文档。
推荐阅读
- python - Tensorflow - 如何创建一个元组数组的数据集
- java - 如何以列表为值打印地图,随着每个列表元素都有自己的值而增长,此外?(爪哇)
- mysql - 编写 SQL 查询以打印表中不包含 '%' 符号的单词
- spring - spring - 如何明确设置primary = false?
- go - 观察 pod 状态的所有变化
- javascript - 如何在nodejs中为数组/对象数据创建层次结构?
- javascript - jquery ajax中的成功事件不起作用
- linux - 在 AIX 服务器中使用 Sed -i 选项。函数无法解析 aix
- c# - Elasticsearch:获取特定商品的订购号
- bluetooth - 通过 HID/HSP 配置文件的蓝牙连接(智能手机/PWA 到 IoT 设备)