我有一个使用MobX的React Native应用程序。我的商店有一个默认对象,当用户通过操作(在Options.js文件中)更新值时,我想在本地保存(React Native' AsyncStorage),以便下一次应用程序打开时,对象未重置为默认值。在首次运行,检查和加载新值时,处理此问题的好方法是什么?
我的RootStore.js看起来像这样:
import { observable, action } from 'mobx';
export default class RootStore {
constructor() {
this.sources = new Sources(this);
}
}
class Sources {
constructor(rootStore) {
this.rootStore = rootStore;
}
@observable
left = [
{
active: 'yes',
side: 'value One',
name: 'value Two',
},
];
//passing in new object from Options.js
@action
updateActiveLeft(data) {
let object = data;
this.left = object;
console.log('New active name set in store - ' + this.left[0].name);
}
答案 0 :(得分:2)
我已更新您的文件,以包含我在所有React Native应用程序中使用的基本模式。我使用async / await语法来处理异步调用,但您可以使用promises或任何您喜欢的模式。您可能还希望将其设置为DRY类以处理所有本地API。请注意,如果您在商店中存储非mobx方法,那么这不会起作用,因为mobx.toJS
没有删除它们,而JSON.stringify
无法将函数序列化。
编辑:修复了编译错误并添加了updateStore()方法。
import { observable, action, toJS } from 'mobx';
import { AsyncStorage } from 'react-native';
import _ from 'lodash';
export default class RootStore {
constructor() {
this.sources = new Sources(this);
// You can move this to your App.js class when your app
// for more control but this will start loading your data
// as soon as RootStore is created.
this.sources.refreshStores();
}
}
class Sources {
@observable
left = [
{
active: 'yes',
side: 'value One',
name: 'value Two',
},
];
//passing in new object from Options.js
@action
updateActiveLeft(data) { // May want to make this a promise or async
let object = data;
// this.left = object; // Now using updateStore to set MobX obs
this.updateStore(toJS(object)).then(() => {
console.log('Data is now saved in AsyncStorage.')
});
}
/**
* Set async data to local memory
* @param newdata {object} An updated store abject
*/
@action
updateStore = async (newdata) => {
try {
const AppData = newdata;
// Set MobX observables with new data
_.forEach(AppData, (value, key) => {
this[key] = value;
});
// Set AsyncStorage
await AsyncStorage.setItem('app', JSON.stringify(AppData));
} catch(e) {
console.log('Could not update app store. [store/App]')
}
}
/**
* Set MobX data from AsyncStorage
*/
@action
refreshStores = async () => {
try {
const RootStore = await this.getStore();
// I store my data in AsyncStorage exactly the same way I store my observables
// so that when I recall them I can just iterate through my object or array
// and set them easily to MobX observables.
_.forEach(RootStore, (value, key) => {
this[key] = value;
});
} catch(e) {
console.log('Could not refresh app store.');
}
}
/**
* Retrieve data from AsyncStorage
*/
@action
getStore = async () => {
try {
// I'm just using RootStore as a storage key name but you can use whatever you want.
// I'm also shortcircuiting the call to async to be replaced with the default values
// in case the store doesn't exist.
let RootStore = await AsyncStorage.getItem('RootStore') || JSON.stringify(toJS(this));
RootStore = JSON.parse(RootStore);
return RootStore;
} catch(e) {
console.log('Could not get data from store.')
}
}
}
答案 1 :(得分:0)
您可以尝试使用mobx-decorators中的@save
装饰器。但请记住@save
是惰性装饰器,并且在第一次访问属性后将加载值。