通知组件删除和计数器ReactJS

问题描述 投票:0回答:1

我想使用图标“X”删除特定通知,但删除后它又重新出现。我是编码初学者,我想尝试本地存储,可以将通知组件存储在本地存储中然后将其删除吗?顺便说一句,我正在使用 ReactJS

import React, { useEffect, useState } from "react";
import { IoMdNotificationsOutline } from "react-icons/io";
import "./notif.css";
import { getDocs, collection } from "firebase/firestore";
import { database } from "../config/firebase";
import { MdCancel } from "react-icons/md";

const NotificationComponent = () => {
    const [productList, setProductList] = useState([]);
    const productCollectionRef = collection(database, "singleProduct");

    async function getProductList() {
        try {
            const data = await getDocs(productCollectionRef);
            const filteredData = data.docs.map((doc) => ({
                ...doc.data(),
                id: doc.id,
            }));
            setProductList(filteredData.reverse());
        } catch (err) {
            console.error(err);
        }
    }

    useEffect(() => {
        getProductList();
    }, []);

    const [showNotifications, setShowNotifications] = useState(false);
    const storedNotifications = JSON.parse(localStorage.getItem("notifications"));
    const [notifications, setNotifications] = useState(storedNotifications);

    useEffect(() => {
        localStorage.setItem("notifications", JSON.stringify(notifications));
        const storedNotifications = JSON.parse(
            localStorage.getItem("notifications"),
        );
        console.log(storedNotifications);
    }, []);

    const [currentDate, setCurrentDate] = useState(new Date());
    const [counter, setCounter] = useState(0);

    const toggleNotifications = () => {
        setShowNotifications(!showNotifications);
        if (showNotifications) {
            setCounter(0); // Reset the counter if showNotifications is true
        }
    };

    function isWithinOneWeek(date) {
        const targetDate = new Date(date);
        const checkWeekAhead = new Date();
        checkWeekAhead.setDate(checkWeekAhead.getDate() + 7);

        return (
            Math.abs(targetDate.getTime() - checkWeekAhead.getTime()) <=
            7 * 24 * 60 * 60 * 1000
        );
    }

    useEffect(() => {
        const timer = setInterval(() => {
            setCurrentDate(new Date());
        }, 1000);

        return () => clearInterval(timer);
    }, []);

    useEffect(() => {
        const newNotifications = [];
        productList.forEach((product) => {
            if (isWithinOneWeek(new Date(product.expirationDate.seconds * 1000))) {
                newNotifications.push({
                    id: product.id,
                    message: (
                        <div className="notificationMessage">
                            <p>
                                The Product: {product.productName} will be expired in one week
                            </p>
                            <p>
                                Product Identifier: {product.uniqueIdentifier}
                                {product.serialNum}
                            </p>
                            <p>
                                {" "}
                                {new Date(
                                    product.expirationDate.seconds * 1000,
                                ).toLocaleDateString()}
                            </p>
                        </div>
                    ),
                });
            } else if (
                currentDate >= new Date(product.expirationDate.seconds * 1000)
            ) {
                newNotifications.push({
                    id: product.id,
                    message: (
                        <div className="notificationMessage">
                            <p>The Product: {product.productName} is expired.</p>
                            <p>
                                Product Identifier: {product.uniqueIdentifier}
                                {product.serialNum}
                            </p>
                            <p>
                                {" "}
                                {new Date(
                                    product.expirationDate.seconds * 1000,
                                ).toLocaleDateString()}
                            </p>
                        </div>
                    ),
                });
            }
        });
        setNotifications(newNotifications);
        localStorage.setItem("notifications", JSON.stringify(newNotifications));
        setCounter(newNotifications.length);
    }, [productList, currentDate]);

    // Function to delete a notification
    const handleDelete = (itemToDelete) => {
        setNotifications(() =>
            notifications.filter((notification) => notification !== itemToDelete),
        );
    };

    return (
        <div className="notification-component">
            <div>
                <h1>{currentDate.toLocaleDateString()}</h1>
            </div>
            <div className="notification-icon" onClick={toggleNotifications}>
                <IoMdNotificationsOutline className="icon" />
                {showNotifications
                    ? null
                    : counter > 0 && (
                            <span className="notification-counter">{counter}</span>
                        )}
            </div>
            {showNotifications && (
                <div className="notification-list">
                    <h3>Notifications</h3>
                    <ul>
                        {notifications.map((notification) => (
                            <li key={notification}>
                                {" "}
                                {/* Use notification.id as the key */}
                                {notification.message}
                                <span
                                    className="deleteNotif"
                                    onClick={() => handleDelete(notification)}
                                >
                                    <MdCancel />
                                </span>
                            </li>
                        ))}
                    </ul>
                </div>
            )}
        </div>
    );
};

export default NotificationComponent;

reactjs notifications local-storage
1个回答
0
投票

删除通知后,您可以将其从状态中删除,但不会从 localStorage 中删除。下一次重新渲染将从本地存储获取通知以及最近删除的通知。这就是您看到通知再次出现的原因。将其从被删除的状态中排除后,然后从 localStorage 中重新获取,因此它会重新出现:

要解决此问题,您应该在突变后更新 localStorage:

    // Function to delete a notification
    const handleDelete = (itemToDelete) => {
        setNotifications(() =>
            notifications.filter((notification) => notification !== itemToDelete),
        );
        
        localStorage.setItem("notifications", JSON.stringify(notifications));
    };
© www.soinside.com 2019 - 2024. All rights reserved.