MobX Store推送日期至数组报错:TypeError: undefined is not an object
问题排查:MobX Store中调用
this.openTimes.push报错 报错原因
核心问题是setOpenTime方法的**this指向丢失**:当你在AppState.addEventListener的回调里调用setOpenTime时,方法的上下文已经不再是StreakStore的实例,导致this.openTimes变成undefined,触发报错。
另外还有一个潜在问题:你在组件初始化时创建了dt变量,后续每次触发回调都会使用同一个初始时间,无法获取实时的激活时间。
解决方案
1. 修复this指向问题(三选一即可)
方案一:在构造函数中绑定this
修改StreakStore.ts的构造函数,手动绑定setOpenTime的this:
class StreakStore { constructor() { makeAutoObservable(this); // 绑定this,确保方法上下文指向Store实例 this.setOpenTime = this.setOpenTime.bind(this); } // ...其他代码不变 }
方案二:用箭头函数定义action方法
箭头函数会自动捕获当前上下文的this,修改StreakStore.ts中的setOpenTime:
@action setOpenTime = (openTime: Datetime) => { this.openTimes.push({...openTime}); }
方案三:在调用时用箭头函数包裹
修改Navigation.tsx中的useEffect回调,通过箭头函数确保调用时的上下文:
useEffect(() => { AppState.addEventListener('change', (state) => { if (state === 'active') { setOpenTime({date: new Date().toString()}); } }); }, []);
2. 修正实时日期获取
把日期创建逻辑放到回调内部,确保每次App激活时获取的是当前时间:
useEffect(() => { AppState.addEventListener('change', (state) => { if (state === 'active') { // 实时获取当前激活时间 const currentDt = new Date(); setOpenTime({date: currentDt.toString()}); } }); }, []);
3. 补充MobX持久化配置(可选但推荐)
你引入了makePersistable但未配置,若需要持久化openTimes数组,需在构造函数中添加配置:
class StreakStore { constructor() { makeAutoObservable(this); makePersistable(this, { name: 'StreakStore', properties: ['openTimes'], storage: AsyncStorage, }); } // ...其他代码不变 }
修改后的关键代码示例
StreakStore.ts(箭头函数方案+持久化配置)
import AsyncStorage from '@react-native-async-storage/async-storage'; import {action, computed, makeAutoObservable} from 'mobx'; import {makePersistable} from 'mobx-persist-store'; export interface Datetime { date: string; } class StreakStore { constructor() { makeAutoObservable(this); makePersistable(this, { name: 'StreakStore', properties: ['openTimes'], storage: AsyncStorage, }); } openTimes: Datetime[] = [ { date: '2022-9-8' } ]; @action setOpenTime = (openTime: Datetime) => { this.openTimes.push({...openTime}); } @computed get info() { return { total: this.openTimes.length, } } } const streakStore = new StreakStore(); export default streakStore;
Navigation.tsx(修正时间获取+依赖数组)
import React, {useEffect} from 'react'; import {NavigationContainer} from '@react-navigation/native'; import {AppState} from 'react-native'; import {LightTheme, DarkTheme} from '../constants/Theme'; import useColorScheme from '../hooks/useColorScheme'; import {RootNavigatorStack} from './RootNavigatorStack'; import {useStore} from '../store/RootStore'; import {observer} from 'mobx-react-lite'; const Navigation = () => { const colorScheme = useColorScheme(); const theme = colorScheme === 'dark' ? DarkTheme : LightTheme; const {setOpenTime} = useStore().streakStore; useEffect(() => { AppState.addEventListener('change', (state) => { if (state === 'active') { setOpenTime({date: new Date().toString()}); } }); }, [setOpenTime]); // 添加setOpenTime到依赖数组,符合React Hooks规范 return ( <NavigationContainer theme={theme}> <RootNavigatorStack /> </NavigationContainer> ); }; export default observer(Navigation);
内容的提问来源于stack exchange,提问作者Nguyễn Hiếu
相关产品推荐
相关产品推荐

