我正在为 Next.js Web 应用程序项目开发聊天原型,并且遇到了删除消息的问题。我希望用户能够在他们发送的消息上看到“删除”按钮,单击它后,它将通过搜索其唯一的 uuid 从存储数据的 PostgreSQL 表中删除消息。我遇到的问题是,单击按钮后,它反而从表中删除了所有消息。
我的猜测是,因为这个 ForumItem 组件正在被映射,所以单击一条消息上的按钮会导致删除函数映射到所有呈现的 ForumItem 组件?我只希望删除按钮所属的消息。
这是来自 ForumItem.js 的所有基本代码(忽略两个日期转换函数):
import { supabase } from '../utils/supabaseClient'
function removeMessage(msgId) {
const deleteMessage = async () => {
let { data: messages, error} = await supabase
.from("chat")
.delete()
.match({chat_id: msgId})
if(!error) {
updater(messages)
}
else {
console.log(error)
}
}
}
export default function ForumItem({ sender, date_sent, message, msgId, updater }) {
const currUser = supabase.auth.user()
let newTime = String(new Date(date_sent)).slice(16,24)
let newDate = String(new Date(date_sent)).slice(4,15)
let formattedDate = convertedDate(newDate)
let name = ""
if (sender == null) {
name = "[Unknown User]"
}
else {
name = String(sender)
}
let userEmail = name.split("@");
let userName = userEmail[0]
return (
<div className = "forumItem">
<h1 style = {{color: 'white'}}>{userName}</h1>
<p style = {{textAlign: 'left', display: 'flex', flexDirection: 'row', justifyContent: 'space-between'}}>
<div className = "forumMessage">{message}</div>
<span style={{color: 'white', float: 'right'}}>
{
(currUser.email == name) && (
<>
<button type = "submit" id = "delete" className = "bg-red-600 rounded px-4 py-0.25" onclick = {
(
removeMessage({msgId})
)
}>Delete</button>
</>
)
}
<i> Sent {formattedDate} {newTime}</i>
</span>
</p>
</div>
)
}
“updater”函数只是在本地保存消息的数组的 useState 的设置器。如果需要,这是通过该数组映射以呈现 ForumItem 组件的论坛页面的代码:
import ForumItem from "../components/ForumItem"
import Header from "../components/Header"
import { useEffect, useState } from 'react'
import Input from "../components/Input"
import { supabase } from '../utils/supabaseClient'
import { Auth } from "@supabase/ui"
export default function forums () {
//const { name } = Auth.useUser()
//console.log(name.user)
//const currentName = "rmillares" //this is default, idk how to carry over username yet
const user = supabase.auth.user()
const badWords = [" kill ", " suicide ", "murder"]
var testDate = new Date().getTime()
const [forumTests, setForumTests] = useState([])
const [error, setError] = useState(null)
useEffect(() => {
fetchMessages()
})
const fetchMessages = async () => {
let { data: messages, error} = await supabase
.from("chat")
.select()
if(!error) {
setForumTests(messages)
}
else {
console.log(error)
}
}
const addMessage = async (msg) => {
let flag1 = true
let currWord = ""
if(msg.length == 0) {
flag1 = false
}
else {
for (let i = 0; i < badWords.length; i++) {
if (msg.includes(badWords[i])) {
flag1 = false
currWord = badWords[i]
}
}
}
if(flag1) {
console.log("reached")
let brandNewDate = new Date().getTime()
const { data, error } = await supabase
.from("chat")
.insert([
{ sender: user.email, date_sent: brandNewDate, message: msg}])
if(!error) {
setForumTests([...forumTests, {'sender': user.email, 'date_sent': brandNewDate, 'message': msg}])
}
else {
console.log(error)
}
console.log(brandNewDate)
}
else {
alert("Your message:\n\n" + msg + "\n\ncontained the word [" + currWord + "], which is not allowed, thus your message failed to send.")
}
}
return (
<div>
<div class = "forumPage">
<Header />
<h1 style = {{fontSize: '32'}}>Forums</h1>
<Input handleSubmit = {addMessage} buttonText = "Send"/>
<div className = "forums">
{
forumTests.slice(0).reverse().map((forum) => (
<ForumItem sender = {forum.sender} date_sent = {forum.date_sent} message = {forum.message} msgId = {forum.chat_id} updater = {setForumTests}/>
))
}
</div>
</div>
</div>
)
}