javascript - 如何使反应停止点击重复元素
问题描述
问题是每次我点击一个有状态的元素时,都会出现两次。例如,如果我单击一个按钮并且单击的结果是在控制台中输出某些内容,它将输出 2 次。但是在这种情况下,每当我单击一个函数时,都会执行两次。
编码:
const getfiles = async () => {
let a = await documentSpecifics;
for(let i = 0; i < a.length; i++) {
var wrt = document.querySelectorAll("#writeto");
var fd = document.querySelector('.filtered-docs');
var newResultEl = document.createElement('div');
var writeToEl = document.createElement('p');
newResultEl.classList.add("result");
writeToEl.id = "writeto";
newResultEl.appendChild(writeToEl);
fd.appendChild(newResultEl);
listOfNodes.push(writeToEl);
listOfContainers.push(newResultEl);
wrt[i].textContent = a[i].data.documentName;
}
}
这里的代码应该创建一个带有段落标签的新 div 元素并从 firebase firestore 获取数据,并将数据写入 p 标签。现在,如果 Firestore 中有 9 个文档并且我单击一个按钮,那么将复制另外 9 个 div。现在总共有 18 个 div,只有 9 个包含实际数据,其余的都是空白的。每次点击它都会继续创建另外 9 个 div。我也知道React.Strictmode
这样做是为了进行一些调试,但我确保将其取出并仍然得到相同的结果。火力基地代码:
//put data in firebase
createFileToDb = () => {
var docName = document.getElementById("title-custom").value; //get values
var specifiedWidth = document.getElementById("doc-width").value;
var specifiedHeight = document.getElementById("doc-height").value;
var colorType = document.getElementById("select-color").value;
parseInt(specifiedWidth); //transform strings to integers
parseInt(specifiedHeight);
firebase.firestore().collection("documents")
.doc(firebase.auth().currentUser.uid)
.collection("userDocs")
.add({
documentName: docName,
width: Number(specifiedWidth), //firebase-firestore method for converting the type of value in the firestore databse
height: Number(specifiedHeight),
docColorType: colorType,
creation: firebase.firestore.FieldValue.serverTimestamp() // it is possible that this is necessary in order to use "orderBy" when getting data
}).then(() => {
console.log("file in database");
}).catch(() => {
console.log("failed");
})
}
//get data
GetData = () => {
return firebase.firestore()
.collection("documents")
.doc(firebase.auth().currentUser.uid)
.collection("userDocs")
.orderBy("creation", "asc")
.get()
.then((doc) => {
let custom = doc.docs.map((document) => {
var data = document.data();
var id = document.id;
return { id, data }
})
return custom;
}).catch((err) => {console.error(err)});
}
waitForData = async () => {
let result = await this.GetData();
return result;
}
//in render
let documentSpecifics = this.waitForData().then((response) => response)
.then((u) => {
if(u.length > 0) {
for(let i = 0; i < u.length; i++) {
try {
//
} catch(error) {
console.log(error);
}
}
}
return u;
});
编辑:firebase auth 运行良好,所以我认为它与问题没有任何关系编辑:这一切都在一个类组件中编辑:单击一个按钮调用该函数createFileToDb
解决方案
我想我找到了问题的答案。基本上,因为这是一个类组件,所以我从渲染中取出了一些东西并放置了一些console.log
语句来看看发生了什么。我注意到的是它在渲染中记录了两次,但不在它之外。所以我把功能拿出来了。这是似乎可以解决我的问题的代码:
contain = () => {
const documentSpecifics = this.waitForData().then((response) => {
var wrt = document.getElementsByClassName('writeto');
for(let i = 0; i < response.length; i++) {
this.setNewFile();
wrt[i].textContent = response[i].data.documentName;
}
return response;
})
this.setState({
docs: documentSpecifics,
docDisplayType: !this.state.docDisplayType
})
}
至于创建元素,我将它们放在一个函数中,以便我可以重用它:
setNewFile = () => {
const wrt = document.querySelector(".writeto");
const fd = document.querySelector("#filtered-docs");
var newResultEl = document.createElement('div');
newResultEl.classList.add("result");
var wrtEl = document.createElement('p');
wrtEl.classList.add("writeto");
fd.appendChild(newResultEl);
newResultEl.appendChild(wrtEl);
}
firebase 和 firestore 代码保持不变。使用 onClick 通过返回中的元素调用这些函数。
推荐阅读
- regex - tshark 转储的 sed 过滤:加速
- sql - SQL 视图中的聚合或类似函数
- entity-framework - 建立关系的惯例
- javascript - nodejs:SyntaxError:意外的标识符
- python - plt.legend() 阻止 matplotlib 显示绘图
- sql-server - SQL Server 中的 Windows 组
- c# - Android 未从 LocalApplicationDirectory 加载字体
- visual-studio - 项目中缺少的文件夹,即使在使用显示所有文件后也不显示
- sql - 如何使用 Transact-SQL (t-sql) 删除尾随字符?
- nosql - 无法在 ArangoDB 中声明变量