Home > Enterprise >  NextJS component takes fade of removed component
NextJS component takes fade of removed component

Time:01-31

So I'm using NextJS and tailwind to create a notification provider for my app, however when I display multiple notifications and the top one gets removed the one underneath it takes over it's fade value, how do I fix this? enter image description here

import { createContext, useState, useContext } from "react";

const Context = createContext();

const Provider = ({ children }) => {
    const [notifications, setNotifications] = useState([]);

    const exposed = {
        addNotification: (type, text, autoClose) => {
            const id = Math.random()
            setNotifications(notifications => [...notifications, { id, type, text, autoClose, fade: false }]);
            if (autoClose) {
                setTimeout(() => {
                    removeNotification(id);
                }, 5000);
            }
        },
    };

    const removeNotification = (id) => {
        setNotifications(notifications => notifications.map(n => n.id === id ? { ...n, fade: true } : n));
        setTimeout(() => {
            setNotifications(notifications => notifications.filter(n => n.id !== id));
        }, 1000);
    }

    return (
        <Context.Provider value={exposed}>
            {children}
            {notifications.length > 0 ? <div className="z-50 fixed top-5 right-5 text-right">
                {notifications.map((notification, index) => {
                    switch (notification.type) {
                        case 'info':
                            return <Info text={notification.text} key={index} remove={() => removeNotification(notification.id)} fade={notification.fade} />
                        /* other cases */
                    }
                })}
            </div> : null}
        </Context.Provider>
    );
}

function Info({ remove, text, fade }) {
    return (
        <div className={`flex items-center w-fit mt-2 mr-0 ml-auto transition-opacity ease-in duration-1000 ${!fade?'opacity-100':'opacity-0'}`}>
            {/* content */}
        </div>
    )
}

export const useProvider = () => useContext(Context);

export default Provider;

CodePudding user response:

There might be other issues to be addressed, but for a list with dynamically changing items, consider to avoid using index as unique key to prevent potential conflicts when the list changes.

Perhaps try use notification.id as key in the posted example:

<Context.Provider value={exposed}>
  {children}
  {notifications.length > 0 ? (
    <div className="z-50 fixed top-5 right-5 text-right">
      {notifications.map((notification, index) => {
        switch (notification.type) {
          case "info":
            return (
              <Info
                text={notification.text}
                //            
  • Related