在反应中使用 addDoc 后清除表单
Clear form after using addDoc in react
我有一个用户可以在点击按钮时输入评论的地方,评论会添加到我的 firestore collection。我只想在单击按钮后清除表单,方法是将我的 formData 设置为其初始状态值,但它不起作用。文档被添加到 collection,但数据保留在输入字段中。有什么想法吗?
谢谢
更新:我发现了我必须将我的表单变成一个受控组件的问题然后我能够在按下按钮后将我的 formData 状态重置为空白
import React, { useState, useEffect } from "react";
import { NavBar, Footer, Home, About } from "./imports";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import { db } from "./firebase-config";
import {
collection,
doc,
updateDoc,
addDoc,
Timestamp,
query,
orderBy,
onSnapshot,
} from "firebase/firestore";
export default function App() {
const [formData, setFormData] = useState([]);
const [numberOfVisitors, setnumberOfVistors] = useState([]);
const [userComments, setUserComments] = useState([]);
const userCommentsRef = collection(db, "user-comments");
const addNewComment = async (event) => {
event.preventDefault();
const newComment = {
name: formData.name,
comment: formData.comment,
date: Timestamp.now(),
};
try {
await addDoc(userCommentsRef, newComment);
setFormData([]); //set state back to initial value after adding a doc to clear all the inputs on the form.
} catch (err) {
console.log(err);
}
};
const handleFormData = (event) => {
setFormData((prevFormData) => {
return {
...prevFormData,
[event.target.name]: event.target.value,
};
});
};
useEffect(() => {
const portfolioStatsRef = collection(db, "portfolio-stats");
const q = query(portfolioStatsRef);
const unsubscribeFromEventListener = onSnapshot(q, (snapshot) => {
const VisitorCountFromDB = snapshot.docs.map((doc) => ({
...doc.data(),
id: doc.id,
}));
setnumberOfVistors(VisitorCountFromDB);
});
return () => unsubscribeFromEventListener();
}, []);
useEffect(() => {
const updateVisitorCount = async () => {
try {
const portfolioStatsDoc = doc(
db,
"portfolio-stats",
numberOfVisitors[0].id
);
const updatedFields = {
visitor_count: numberOfVisitors[0].visitor_count + 1,
};
await updateDoc(portfolioStatsDoc, updatedFields);
} catch (err) {
console.log(err + " at updateVisitorCount function");
}
};
if (!numberOfVisitors.length) return;
let sessionKey = sessionStorage.getItem("sessionKey");
if (sessionKey === null) {
sessionStorage.setItem("sessionKey", "randomString");
updateVisitorCount();
}
}, [numberOfVisitors]);
useEffect(() => {
const q = query(userCommentsRef, orderBy("date", "desc"));
onSnapshot(q, (snapshot) => {
const userCommentsFromDB = snapshot.docs.map((doc) => ({
...doc.data(),
id: doc.id,
}));
setUserComments(userCommentsFromDB);
});
}, [userCommentsRef]);
const currentNumberOfVisitors = numberOfVisitors.map((visitors) => {
return (
<h2 className="p-3 mb-0 bg-dark bg-gradient text-white" key={visitors.id}>
Number of vistors: {visitors.visitor_count}
</h2>
);
});
const listOfUserComments = userComments.map((comment) => {
return (
<li className="list-group-item" key={comment.id}>
<div className="d-flex w-100 justify-content-center">
<h5 className="mb-1">{comment.name}</h5>
<small>{comment.date.toDate().toDateString()}</small>
</div>
<p className="d-flex justify-content-center mb-1">{comment.comment}</p>
</li>
);
});
return (
<>
<div className="d-flex flex-column overflow-hidden min-vh-100 vh-100">
<NavBar />
<div className="row">
<div className="col text-center">
{numberOfVisitors.length === 0 && (
<h2 className="p-3 mb-0 bg-dark bg-gradient text-danger">
Sorry, the Firestore free tier quota has been met for today.
Please come back tomorrow to see portfilio stats.
</h2>
)}
{currentNumberOfVisitors}
</div>
</div>
<div className="bg-image">
<div className="postion-relative">
<main className="flex-grow-1">
<div className="container-fluid p-0">
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
<div className="row">
<div className="center-items col">
<h4 className="">Comments</h4>
</div>
</div>
<div className="row">
<div className="center-items col">
<div className="comments-container">
{userComments.length === 0 && (
<h4 className="text-danger bg-dark m-1 p-1">
Sorry, the Firestore free tier quota has been met
for today. Please come back tomorrow to see
portfilio comments.
</h4>
)}
{listOfUserComments}
</div>
</div>
</div>
<div className="row">
<div className="center-items col">
<h4 className="text-dark">Leave a comment</h4>
</div>
</div>
<div className="row">
<div className="center-items col">
<form className="comment-form">
<div className="form-floating mb-3">
<input
type="text"
className=" form-control bg-transparent "
id="floatingInput"
name="name"
onChange={handleFormData}
/>
<label htmlFor="floatingInput">Name</label>
</div>
<div className="form-floating">
<textarea
className=" form-control form-textarea-field bg-transparent mb-1"
name="comment"
id="floatingTextarea"
onChange={handleFormData}
/>
<label htmlFor="floatingTextarea">Comment</label>
</div>
<div className="d-grid">
<button
className="btn btn-primary mb-4"
onClick={addNewComment}
>
Add Comment
</button>
</div>
</form>
</div>
</div>
</Router>
</div>
</main>
</div>
</div>
<Footer />
</div>
</>
);
}
我认为如果您将空对象添加到 setFormData 将会起作用,如下所示:setFormData({})
但如果没有,您可以使用循环清空每个键,如下所示:
let tempFormData;
for(const [key, value] of Object.entries(formData)) {tempFormData = { [key] : '' }}
setFormData(tempFormData)
我有一个用户可以在点击按钮时输入评论的地方,评论会添加到我的 firestore collection。我只想在单击按钮后清除表单,方法是将我的 formData 设置为其初始状态值,但它不起作用。文档被添加到 collection,但数据保留在输入字段中。有什么想法吗?
谢谢
更新:我发现了我必须将我的表单变成一个受控组件的问题然后我能够在按下按钮后将我的 formData 状态重置为空白
import React, { useState, useEffect } from "react";
import { NavBar, Footer, Home, About } from "./imports";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import { db } from "./firebase-config";
import {
collection,
doc,
updateDoc,
addDoc,
Timestamp,
query,
orderBy,
onSnapshot,
} from "firebase/firestore";
export default function App() {
const [formData, setFormData] = useState([]);
const [numberOfVisitors, setnumberOfVistors] = useState([]);
const [userComments, setUserComments] = useState([]);
const userCommentsRef = collection(db, "user-comments");
const addNewComment = async (event) => {
event.preventDefault();
const newComment = {
name: formData.name,
comment: formData.comment,
date: Timestamp.now(),
};
try {
await addDoc(userCommentsRef, newComment);
setFormData([]); //set state back to initial value after adding a doc to clear all the inputs on the form.
} catch (err) {
console.log(err);
}
};
const handleFormData = (event) => {
setFormData((prevFormData) => {
return {
...prevFormData,
[event.target.name]: event.target.value,
};
});
};
useEffect(() => {
const portfolioStatsRef = collection(db, "portfolio-stats");
const q = query(portfolioStatsRef);
const unsubscribeFromEventListener = onSnapshot(q, (snapshot) => {
const VisitorCountFromDB = snapshot.docs.map((doc) => ({
...doc.data(),
id: doc.id,
}));
setnumberOfVistors(VisitorCountFromDB);
});
return () => unsubscribeFromEventListener();
}, []);
useEffect(() => {
const updateVisitorCount = async () => {
try {
const portfolioStatsDoc = doc(
db,
"portfolio-stats",
numberOfVisitors[0].id
);
const updatedFields = {
visitor_count: numberOfVisitors[0].visitor_count + 1,
};
await updateDoc(portfolioStatsDoc, updatedFields);
} catch (err) {
console.log(err + " at updateVisitorCount function");
}
};
if (!numberOfVisitors.length) return;
let sessionKey = sessionStorage.getItem("sessionKey");
if (sessionKey === null) {
sessionStorage.setItem("sessionKey", "randomString");
updateVisitorCount();
}
}, [numberOfVisitors]);
useEffect(() => {
const q = query(userCommentsRef, orderBy("date", "desc"));
onSnapshot(q, (snapshot) => {
const userCommentsFromDB = snapshot.docs.map((doc) => ({
...doc.data(),
id: doc.id,
}));
setUserComments(userCommentsFromDB);
});
}, [userCommentsRef]);
const currentNumberOfVisitors = numberOfVisitors.map((visitors) => {
return (
<h2 className="p-3 mb-0 bg-dark bg-gradient text-white" key={visitors.id}>
Number of vistors: {visitors.visitor_count}
</h2>
);
});
const listOfUserComments = userComments.map((comment) => {
return (
<li className="list-group-item" key={comment.id}>
<div className="d-flex w-100 justify-content-center">
<h5 className="mb-1">{comment.name}</h5>
<small>{comment.date.toDate().toDateString()}</small>
</div>
<p className="d-flex justify-content-center mb-1">{comment.comment}</p>
</li>
);
});
return (
<>
<div className="d-flex flex-column overflow-hidden min-vh-100 vh-100">
<NavBar />
<div className="row">
<div className="col text-center">
{numberOfVisitors.length === 0 && (
<h2 className="p-3 mb-0 bg-dark bg-gradient text-danger">
Sorry, the Firestore free tier quota has been met for today.
Please come back tomorrow to see portfilio stats.
</h2>
)}
{currentNumberOfVisitors}
</div>
</div>
<div className="bg-image">
<div className="postion-relative">
<main className="flex-grow-1">
<div className="container-fluid p-0">
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
<div className="row">
<div className="center-items col">
<h4 className="">Comments</h4>
</div>
</div>
<div className="row">
<div className="center-items col">
<div className="comments-container">
{userComments.length === 0 && (
<h4 className="text-danger bg-dark m-1 p-1">
Sorry, the Firestore free tier quota has been met
for today. Please come back tomorrow to see
portfilio comments.
</h4>
)}
{listOfUserComments}
</div>
</div>
</div>
<div className="row">
<div className="center-items col">
<h4 className="text-dark">Leave a comment</h4>
</div>
</div>
<div className="row">
<div className="center-items col">
<form className="comment-form">
<div className="form-floating mb-3">
<input
type="text"
className=" form-control bg-transparent "
id="floatingInput"
name="name"
onChange={handleFormData}
/>
<label htmlFor="floatingInput">Name</label>
</div>
<div className="form-floating">
<textarea
className=" form-control form-textarea-field bg-transparent mb-1"
name="comment"
id="floatingTextarea"
onChange={handleFormData}
/>
<label htmlFor="floatingTextarea">Comment</label>
</div>
<div className="d-grid">
<button
className="btn btn-primary mb-4"
onClick={addNewComment}
>
Add Comment
</button>
</div>
</form>
</div>
</div>
</Router>
</div>
</main>
</div>
</div>
<Footer />
</div>
</>
);
}
我认为如果您将空对象添加到 setFormData 将会起作用,如下所示:setFormData({})
但如果没有,您可以使用循环清空每个键,如下所示:
let tempFormData;
for(const [key, value] of Object.entries(formData)) {tempFormData = { [key] : '' }}
setFormData(tempFormData)