You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS中使用Mobx Observer展示MUI Snackbar失效问题排查

问题分析与解决方案

核心问题1:Mobx 6+ 未初始化响应式

在Mobx 6及以上版本中,使用@observable、@action、@computed这类装饰器语法时,必须在类的构造函数中调用makeObservable(this)来启用响应式能力。你的AlertsStore没有构造函数,也未执行初始化操作,导致所有装饰器完全不生效——Mobx无法追踪alerts数组的变化,@observer组件自然不会触发重渲染。

核心问题2:push逻辑导致current指向旧的隐藏告警

调用push添加新告警时,你先执行hide()将当前第一个告警的display设为false,再把新告警推到数组末尾。此时current计算属性返回的仍是数组第一个元素(已隐藏的旧告警),Snackbar的open属性为false,自然无法显示新告警。


具体修复方案

1. 修复Mobx响应式初始化

修改AlertsStore,添加构造函数并完成响应式初始化:

import {just, Maybe, nothing} from 'maybeasy';
import {action, computed, observable, makeObservable} from 'mobx';
import {Alert} from "../base/BaseAlert";

class AlertsStore {
  @observable
  alerts: Alert[] = [];

  constructor() {
    // 关键:启用装饰器对应的响应式能力
    makeObservable(this);
  }

  @computed
  get current(): Maybe<Alert> {
    return this.alerts.length === 0 ? nothing() : just(this.alerts[0]);
  }

  @action
  hide = () => {
    if (this.alerts.length > 0) {
      this.alerts[0].display = false;
    }
  };

  @action
  process = () => {
    this.alerts = this.alerts.slice(1);
  };

  @action
  push = (alert: Alert) => {
    // 调整逻辑:先移除旧告警,再添加新告警
    this.alerts = [{...alert, display: true}];
  };
}

const alertsStore = new AlertsStore();
export default alertsStore;

2. 优化Snackbar的关闭逻辑(可选,用于队列式告警场景)

如果需要实现“依次显示多个告警”的队列逻辑,可调整Snackbar的关闭回调,确保隐藏后自动移除旧告警,让下一个告警成为当前显示项:

@observer
export class Alerts extends React.Component {
  render() {
    return alertsStore.current.cata({
      Just: alert => (
        <Snackbar
          anchorOrigin={{vertical: 'top', horizontal: 'right'}}
          open={alert.display}
          onClose={() => {
            alertsStore.hide();
            // 延迟执行process,确保Snackbar动画完成后再移除旧告警
            setTimeout(() => alertsStore.process(), 300);
          }}
          message={alert.message}
          autoHideDuration={1000}
        />
      ),
      Nothing: () => <></>,
    });
  }
}

同时修改push方法,保留队列逻辑:

@action
push = (alert: Alert) => {
  // 如果当前有正在显示的告警,先隐藏并移除
  if (this.alerts.length > 0) {
    this.hide();
    this.process();
  }
  this.alerts.push({...alert, display: true});
};

3. 确保Alert对象属性可观察(可选)

如果需要单独追踪Alert对象内部属性(如display)的变化,可将创建Alert的函数改为返回可观察对象:

import {observable} from 'mobx';

export const alert = (message: string, kind: Alert['kind']): Alert =>
  observable({
    message,
    kind,
    display: true,
  } as Alert);

验证步骤

  1. 先完成Mobx响应式初始化的修复,确认告警数组的变化能被Mobx追踪。
  2. 测试登录错误场景,观察Snackbar是否正常显示。
  3. 如果需要队列功能,再调整对应的关闭和push逻辑。

内容的提问来源于stack exchange,提问作者Jun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:10:15