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

在React useMemo中调用MobX Store方法遇ESLint警告的优化问询

问题分析与解决方案

当前做法的合理性

你的代码能正常运行,但ESLint警告确实有道理:useMemo回调里并没有直接引用store.role,而是通过store.checkRole间接访问,所以ESLint无法识别这个隐式依赖,才会提示store.role是不必要的。这种写法虽然能达到缓存效果,但依赖数组的写法不符合规范,而且其实完全没必要用useMemo——因为你已经用observer包裹了组件,MobX会自动帮你追踪响应式依赖。

更优实现方案

方案1:去掉useMemo,直接利用MobX的observer特性

observer组件会自动追踪内部用到的所有MobX响应式值(这里就是store.role),只有当role变化时,才会重新计算store.checkRole('ADMIN')的结果。其他无关的渲染触发(比如点击Force Render按钮)不会重复计算,因为role没变化。修改后的组件代码:

const App = observer(() => {
    const [, forceRender] = useReducer((prev) => prev + 1, 0)
    const store = useContext(StoreContext)

    // 直接调用,observer会自动缓存结果,仅在role变化时重新计算
    const isHaveAccess = store.checkRole('ADMIN')

    return (
        <div>
            {isHaveAccess ? 'Access allowed' : 'Access denied'}
            <button onClick={() => store.setRole('ADMIN')}>Set Role</button>
            <button onClick={forceRender}>Force Render</button>
        </div>
    );
})

方案2:若坚持用useMemo,调整依赖数组或内联逻辑

如果一定要保留useMemo,有两种修正方式:

  • 内联checkRole的逻辑,让ESLint能识别到直接依赖store.role:
    const isHaveAccess = useMemo(() => {
        return store.role === 'ADMIN'
    }, [store.role])
    
  • 或者只依赖store.role(因为checkRole的逻辑只和role相关,store本身是稳定的单例,不需要加入依赖):
    const isHaveAccess = useMemo(() => {
        return store.checkRole('ADMIN')
    }, [store.role])
    

方案3:正确使用带参数的computed

你之前尝试的带参数computed可能用法有误,正确的写法是让checkRole成为一个返回函数的computed getter,这样MobX会追踪role的变化,当role更新时,这个函数会重新生成,确保调用时拿到最新值:

class Store {
    constructor() {
        makeAutoObservable(this)
    }

    role: string = ""

    setRole(name: string) {
        this.role = name
    }

    // 带参数的computed,返回一个闭包函数
    get checkRole() {
        return (name: string) => this.role === name
    }
}

组件里依然可以直接调用store.checkRole('ADMIN'),observer会自动处理响应式追踪,不需要额外的useMemo。

总结

最优方案是方案1:去掉useMemo,直接利用observer的响应式特性。MobX的observer已经帮你做了组件级别的缓存优化,手动加useMemo反而画蛇添足,还会引发ESLint警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 21:55:24