如何在发货后禁用活动项目?

How to disable an active item after dispatch?

我想创建在设定的秒数后过期的通知。

我创建了一个 属性,它是 'active',当切换到 false 时它会隐藏。

理想情况下,最好在切片中自动设置到期时间,即 运行 disable reducer 在 运行time of the notify reducer 但我不确定这是不是一个好习惯,我也不确定如何实现它。

实现这一目标的最佳方法是什么?我想在每个项目上添加一个到期日期,但由于 'active' 字段已经存在,我想设置一个超时并在 3 秒后将其切换为 false..

通知组件:

export function Notification() {
    const dispatch = useDispatch();

    function disableAlert(id: number) {
        dispatch(disable({'id' : id}));
    }

    const notification_list = useSelector(getNotification);
    if (notification_list && notification_list.length > 0) {
        return notification_list.map((notification: any, index: number) =>
                notification.active ?
                    <Alert onClose={() => disableAlert(index)} style={{bottom: 50 * index}} severity={notification.mode}>{notification.message}</Alert> :
                    console.log(notification)
        )
    }

    return <></>
}

目前我有这些切片:

const disableMessage = (state: any, message_id: number) => {
    return state.messages.map((message:any) => message.id === message_id ?
        {...message, active: !message.active} :
        message
    );
}

export const notificationSlice = createSlice({
    name: 'notification',
    initialState: initialState,
    reducers: {
        notify: (state, action) => {
            const { message, mode, active } = action.payload;
            state.messages.push({id: state.messages.length , message : message, mode: mode, active: active});
        },
        disable: (state, action) => {
            const { id } = action.payload;
            state.messages = disableMessage(state, id);
        }
    }
})

按照惯例,reducer 从不包含任何类型的逻辑。我建议坚持这个。

这将留下操作或通知组件。对我来说,将禁用与个别通知的呈现联系起来更有意义,所以我会在那里开始超时。

理想情况下,您可以将 <Alert/> 组件拆分为表示和逻辑。类似于:

const NotificationAlert = ({ disableAlert, id }) => {
  const notification = useSelector((state) => selectNotificationById(state, id));

  const handleClick = useCallback(() => {
    disableAlert(id);
  }, [disableAlert, id]);

  useEffect(() => {
    setTimeout(() => disableAlert(id), 3000);
  }, [disableAlert]);

  return (
    <Alert
      onClose={handleClick}
      style={{bottom: 50 * id}}
      severity={notification.mode}>{notification.message}</Alert> 
};

export function Notification() {
    const dispatch = useDispatch();

    // memoize handler with useCallback
    const disableAlert = useCallback((id: number) => {
        dispatch(disable({'id' : id}));
    }, [dispatch]);

    // Filter for active notifications already in your selector
    const notificationIds = useSelector(getActiveNotificationIds);

    return notificationIds.map((id) =>
        <NotificationAlert disableAlert={disableAlert} id={id} />
    );
}

此外,请确保您的 disableAlert 操作将 active 设置为 false 而不是切换它!