所以我基本上创建了一个管理仪表板,其中有一个表单,在其中我可以通过他/她的电子邮件 ID 搜索用户。完成后,数据可见(名字、姓氏和角色)。然后我可以修改这些字段,然后点击更新按钮。完成后,我在表单中所做的所有更改都应反映在我的 firebase/firestore 的后端中。
请找到我的代码。
注意我发现的另一个错误是,即使我试图获取 uid 并放入 console.log ..我在控制台中仍然未定义。
import { collection, getDocs, query, where, doc, updateDoc, deleteDoc } from "firebase/firestore";
import React, { useState } from "react";
import { auth, db } from "./firebase";
import { toast } from "react-toastify";
function UpdateUser() {
const [email, setEmail] = useState("");
const [userData, setUserData] = useState({});
const [isEditable, setIsEditable] = useState(false);
const handleSearch = async (e) => {
e.preventDefault();
try {
const q = query(collection(db, "Users"), where("email", "==", email));
const querySnapshot = await getDocs(q);
if (querySnapshot.empty) {
toast.error("User not found!");
return;
}
const userDoc = querySnapshot.docs[0];
setUserData(userDoc.data());
setIsEditable(true);
console.log("Fetched user data:", userData);
console.log(userDoc.data);
const x = userData.uid;
console.log(x);
} catch (error) {
console.error("Error fetching user:", error.message);
toast.error("Error fetching user data!");
}
};
const handleUpdate = async (e) => {
e.preventDefault();
if (!email) {
console.error("Email cannot be empty.");
toast.error("Error updating user: Email is required.");
return;
}
try {
const userRef = doc(db, "Users", userData.uid);
await updateDoc(userRef, { ...userData, email });
toast.success("User updated successfully!");
setUserData({});
setIsEditable(false);
} catch (error) {
console.error("Error updating user:", error.message);
toast.error("Error updating user data!");
}
};
const handleDelete = async () => {
if (window.confirm("Are you sure you want to delete this user?")) {
if (!userData.uid) {
console.error("User data missing ID. Cannot delete.");
toast.error("Error deleting user: User data incomplete.");
return;
}
try {
const userRef = doc(db, "Users", userData.uid);
await deleteDoc(userRef);
toast.success("User deleted successfully!");
setUserData({});
setIsEditable(false);
} catch (error) {
console.error("Error deleting user:", error.message);
toast.error("Error deleting user data!");
}
}
};
return (
<form onSubmit={handleSearch}>
<h3>Update User</h3>
<div className="mb-3">
<label>Email address</label>
<input
type="email"
className="form-control"
placeholder="Enter email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
disabled={isEditable}
style={{ marginBottom: "5px" }}
/>
<button type="submit" className="btn btn-primary ms-2">
Search
</button>
</div>
{isEditable && (
<>
<div className="mb-3">
<label>First name</label>
<input
type="text"
className="form-control"
placeholder="First name"
value={userData.firstName || ""}
onChange={(e) => setUserData({ ...userData, firstName: e.target.value })}
disabled={!isEditable}
/>
</div>
<div className="mb-3">
<label>Last name</label>
<input
type="text"
className="form-control"
placeholder="Last name"
value={userData.lastName || ""}
onChange={(e) => setUserData({
...userData, lastName: e.target.value
})}
disabled={!isEditable}
/>
</div>
<div className="mb-3">
<label htmlFor="role">ROLE</label>
<select
id="role"
className="form-control"
value={userData.role || ""}
onChange={(e) => setUserData({ ...userData, role: e.target.value })}
disabled={!isEditable}
>
<option value="SME">SME</option>
<option value="Agent">Agent</option>
<option value="Admin">Admin</option>
</select>
</div>
<div className="d-grid">
<button type="submit" className="btn btn-primary" onClick={handleUpdate} disabled={!isEditable}>
Update
</button>
<button type="button" className="btn btn-danger ms-2" onClick={handleDelete} disabled={!isEditable}>
Delete
</button>
</div>
</>
)}
</form>
);
}
export default UpdateUser;
问题出在表单的实现上。您有一个
onsubmit
来表示本质上是 2 种形式。在您的代码中,更新单击函数转到 handleUpdate
并实现 e.preventDefault()
,这允许它跳过继续执行 handleUpdate
函数的默认功能,并移出该函数并转到 handleSubmit
函数。
因此,您输入数据的代码从未运行。您可以执行以下操作:-
Apporach 1(从handleUpdate中删除e.preventDefault)
import { collection, getDocs, query, where, doc, updateDoc, deleteDoc } from "firebase/firestore";
import React, { useState } from "react";
import { auth, db } from "./firebase";
import { toast } from "react-toastify";
function UpdateUser() {
const [email, setEmail] = useState("");
const [userData, setUserData] = useState({});
const [isEditable, setIsEditable] = useState(false);
const handleSearch = async (e) => {
e.preventDefault();
try {
const q = query(collection(db, "Users"), where("email", "==", email));
const querySnapshot = await getDocs(q);
if (querySnapshot.empty) {
toast.error("User not found!");
return;
}
const userDoc = querySnapshot.docs[0];
setUserData(userDoc.data());
setIsEditable(true);
console.log("Fetched user data:", userData);
console.log(userDoc.data);
const x = userData.uid;
console.log(x);
} catch (error) {
console.error("Error fetching user:", error.message);
toast.error("Error fetching user data!");
}
};
const handleUpdate = async (e) => {
// Removed preventdefault from here
if (!email) {
console.error("Email cannot be empty.");
toast.error("Error updating user: Email is required.");
return;
}
try {
const userRef = doc(db, "Users", userData.uid);
await updateDoc(userRef, { ...userData, email });
toast.success("User updated successfully!");
setUserData({});
setIsEditable(false);
} catch (error) {
console.error("Error updating user:", error.message);
toast.error("Error updating user data!");
}
};
const handleDelete = async () => {
if (window.confirm("Are you sure you want to delete this user?")) {
if (!userData.uid) {
console.error("User data missing ID. Cannot delete.");
toast.error("Error deleting user: User data incomplete.");
return;
}
try {
const userRef = doc(db, "Users", userData.uid);
await deleteDoc(userRef);
toast.success("User deleted successfully!");
setUserData({});
setIsEditable(false);
} catch (error) {
console.error("Error deleting user:", error.message);
toast.error("Error deleting user data!");
}
}
};
return (
<form onSubmit={handleSearch}>
<h3>Update User</h3>
<div className="mb-3">
<label>Email address</label>
<input
type="email"
className="form-control"
placeholder="Enter email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
disabled={isEditable}
style={{ marginBottom: "5px" }}
/>
<button type="submit" className="btn btn-primary ms-2">
Search
</button>
</div>
{isEditable && (
<>
<div className="mb-3">
<label>First name</label>
<input
type="text"
className="form-control"
placeholder="First name"
value={userData.firstName || ""}
onChange={(e) => setUserData({ ...userData, firstName: e.target.value })}
disabled={!isEditable}
/>
</div>
<div className="mb-3">
<label>Last name</label>
<input
type="text"
className="form-control"
placeholder="Last name"
value={userData.lastName || ""}
onChange={(e) => setUserData({
...userData, lastName: e.target.value
})}
disabled={!isEditable}
/>
</div>
<div className="mb-3">
<label htmlFor="role">ROLE</label>
<select
id="role"
className="form-control"
value={userData.role || ""}
onChange={(e) => setUserData({ ...userData, role: e.target.value })}
disabled={!isEditable}
>
<option value="SME">SME</option>
<option value="Agent">Agent</option>
<option value="Admin">Admin</option>
</select>
</div>
<div className="d-grid">
<button type="submit" className="btn btn-primary" onClick={handleUpdate} disabled={!isEditable}>
Update
</button>
<button type="button" className="btn btn-danger ms-2" onClick={handleDelete} disabled={!isEditable}>
Delete
</button>
</div>
</>
)}
</form>
);
}
export default UpdateUser;
Apporach 2(创建 2 个单独的表格)- 推荐
添加2种不同的表单,分别处理搜索和编辑功能。