上下文:交互式评论部分CRUD应用程序
删除评论时,用户单击“删除”按钮,该按钮将打开一个模式,要求他们确认删除。该部分(模式打开/关闭和删除评论)工作正常。
我想添加的是一旦用户确认删除并且评论被删除后的警报/闪光通知。我能够在更新评论时实现这一点,但是当使用完全相同的方法进行删除时,由于某种原因,警报没有呈现。
我有一种感觉,这与该组件使用模态有关,但我无法弄清楚到底是什么在阻塞。
我尝试过的:
DeleteConfirmationModal
中设置警报状态和 showAlert 函数(而不是从父组件传递它){alert.show && <Alert {...alert} showAlert={showAlert} />}
置于 Modal
内或置于 article
aside
元素提供高 z 索引下面是我的代码。如果有人能帮我解决这个问题,我将不胜感激。
const UserActionButtons = ({ comment, isEditing, isMobile, isReply, isCurrentUser, onDelete, editComment, handleClickReply}: UserActionButtonsProps) => {
const [isDeleteModalOpen, setDeleteModalOpen] = useState<boolean>(false)
const handleOpenConfirmationModal = (): void => {
setDeleteModalOpen(true)
}
const handleCloseConfirmationModal = (): void => {
setDeleteModalOpen(false)
}
return (
<>
{isCurrentUser ?
(<div className={`${isEditing && isMobile ? 'hidden' : 'cta-button'}`}>
<div className='flex items-center fill-primary-red-soft hover:fill-primary-red-pale text-primary-red-soft hover:text-primary-red-pale '>
<DeleteIcon />
<p className="font-medium mr-4"
onClick={() => handleOpenConfirmationModal()}
> Delete</p>
</div>
<DeleteConfirmationModal
isOpen={isDeleteModalOpen}
onDelete={onDelete}
onCancel={handleCloseConfirmationModal}
comment={comment}
isReply={isReply}
/>
<div className='flex items-center cta-button-blue'>
<EditIcon />
<p className="font-medium"
onClick={editComment}
> Edit</p>
</div>
</div>
) : !isEditing &&
(<div className='cta-button cta-button-blue'>
<ReplyIcon />
<p className="font-medium"
onClick={handleClickReply}
> Reply</p>
</div>)}
</>
)
}
const DeleteConfirmationModal = ({
isOpen,
comment,
isReply,
onCancel,
onDelete
}: DeleteConfirmationModalProps) => {
const { id } = comment
const [alert, setAlert] = useState<AlertInterface>({ show: false, type: '', text: '' })
const showAlert = (show = false, type = '', text = ''): void => {
setAlert({ show, type, text })
}
const deleteComment = (id: number, deletedComment?: MessageMeta): void => {
onDelete(id, deletedComment)
showAlert(true, 'success', 'Comment deleted!')
// console.log(alert.show)
}
useEffect(() => {
console.log(alert)
}, [alert])
return (
<>
{alert.show && <Alert {...alert} showAlert={showAlert} />}
<Modal isOpen={isOpen}>
<article className='flex flex-col gap-y-4'>
<h4 className='font-medium text-xl text-neutral-blue-dark'>Delete comment</h4>
<p className='text-neutral-blue-grayish'>Are you sure you want to delete this comment? This will remove the comment and can't be undone.</p>
<div className='flex gap-x-2 justify-between'>
<button className='bg-neutral-blue-grayish text-white font-medium px-4 sm:px-8 py-3 uppercase rounded-lg border-none w-6/12'
onClick={onCancel}>No, cancel</button>
<button className='bg-primary-red-soft text-white font-medium px-4 sm:px-8 py-3 uppercase rounded-lg border-none w-6/12'
onClick={() => deleteComment(id, isReply ? comment : undefined)}
>Yes, delete</button>
</div>
</article>
</Modal >
</>
)
}
const Alert = ({
type,
text,
showAlert
}: AlertProps) => {
console.log('alert renders')
useEffect(() => {
const timeout = setTimeout(() => {
showAlert()
}, 3000)
return () => clearTimeout(timeout)
}, [])
return (
<aside className={`${type === 'success' ? 'bg-primary-green-success' : 'bg-primary-red-soft'} text-white fixed bottom-5 right-5 p-4 z-50`}>{text}</aside>
)
}
const Modal = ({
isOpen,
children
}: ModalProps) => {
const [isModalOpen, setModalOpen] = useState(isOpen)
const modalRef = useRef<HTMLDialogElement | null>(null)
useEffect(() => {
setModalOpen(isOpen)
}, [isOpen])
useEffect(() => {
const modalElement = modalRef.current
if (modalElement) {
if (isModalOpen) {
modalElement.showModal()
} else {
modalElement.close()
}
}
}, [isModalOpen])
return (
<dialog ref={modalRef}
className={'p-4 sm:p-6 rounded-lg min-w-20 max-w-xs sm:max-w-sm cursor-default'}>
{children}
</dialog>
)
}
我实际上找到了我上面分享的代码中没有的解决方案 基本上因为我递归地渲染评论,所以我还需要将
showAlert
属性传递给 Comment 组件本身
我还将状态提升到最高父级
{comment.replies?.length !== 0 ? (
<div className='flex w-full'>
<div className='w-0.5 bg-neutral-gray-light md:ml-12'></div>
<div className='pl-6 md:pl-12 max-w-full flex-grow'>
{comment.replies?.map((reply) =>
(<Comment
key={reply.id}
comment={reply}
currentUser={currentUser}
commentList={commentList}
onReply={onReply}
onEdit={onEdit}
onDelete={onDelete}
onScoreChange={onScoreChange}
showAlert={showAlert}
/>))}
</div>
</div>) : null}