MobX中makeAutoObservable未自动标记方法为action的问题
问题描述
我使用MobX创建了ModalState状态类,在构造函数中调用makeAutoObservable(this),期望它自动将修改可观察状态的方法标记为action。但实际使用时,在React组件中直接调用modalState.close方法无法触发状态变更,必须用action包裹该调用才能生效。想知道如何实现直接调用store中的action方法,无需手动包裹?
相关代码
状态类代码
class ModalState { opened = false constructor() { makeAutoObservable(this) } open() { this.opened = true } } let modalState: ModalState export function getModalState() { if (!modalState) modalState = new ModalState() return modalState }
组件代码(无效版本)
const MyModal = observer(() => { const [modalState] = useState(() => getModalState()) return ( <Modal opened={modalState.opened} onClose={modalState.close}> ... </Modal> ) })
修复后的组件代码
const MyModal = observer(() => { const [modalState] = useState(() => getModalState()) const close = action(() => modalState.close()) return ( <Modal opened={modalState.opened} onClose={close}> ... </Modal> ) })
解决方案
1. 补全状态类中缺失的close方法
你的ModalState类里只定义了open方法,没有实现close方法,这是核心问题。makeAutoObservable只能将类中已存在的方法自动标记为action,补上close方法后,MobX会自动将其处理为action:
class ModalState { opened = false constructor() { makeAutoObservable(this) } open() { this.opened = true } // 新增close方法 close() { this.opened = false } }
2. 移除多余的useState缓存
getModalState已经实现了单例模式,直接在组件中调用获取实例即可,不需要用useState存储。useState在这里属于冗余代码,还可能引发不必要的引用问题:
const MyModal = observer(() => { const modalState = getModalState() return ( <Modal opened={modalState.opened} onClose={modalState.close}> ... </Modal> ) })
原理说明
makeAutoObservable(this)会自动把类中所有实例方法标记为action,只要方法是直接定义在类中的,就能自动具备action的特性——修改可观察状态后自动触发组件重渲染。之前的问题本质是缺少close方法,导致你调用的modalState.close不存在(或未被MobX处理为action),手动用action包裹相当于临时创建了一个合法的action来修改状态。
内容的提问来源于stack exchange,提问作者Shade
相关产品推荐
相关产品推荐

