NextJS通知组件移除时下方组件继承fade属性问题修复咨询
修复NextJS+Tailwind通知组件的fade属性继承问题
问题描述:使用NextJS和Tailwind构建通知组件时,当展示多条通知,移除顶部通知后,下方的通知会意外继承被移除通知的fade属性,表现为下方通知突然消失(对应效果:顶部通知淡出后,后续通知直接消失而非正常显示)。
问题代码
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;
修复方案
问题根源在于列表渲染时使用了index作为key。当顶部通知被删除后,后续通知的index会向前偏移,React会复用之前的组件实例,导致旧组件的fade状态被错误继承。
只需要修改列表渲染的key值,将key={index}替换为key={notification.id}:
{notifications.map((notification) => { switch (notification.type) { case 'info': return <Info text={notification.text} key={notification.id} remove={() => removeNotification(notification.id)} fade={notification.fade} /> /* other cases */ } })}
补充说明
- 每个通知对象都有唯一的
id(通过Math.random()生成),用它作为key可以确保React能准确识别每个列表项,不会因为列表项顺序变化而复用错误的组件实例。 - 保持
removeNotification逻辑不变,依然先标记fade为true,等待动画完成后再删除通知项,这样就能保证每个通知的淡出动画独立执行,不会影响其他通知。
内容的提问来源于stack exchange,提问作者AwiJol
相关产品推荐
相关产品推荐

