Я пытаюсь сделать домашнее задание в React-Native, TypeScript и Mobx для Android. После более 5 часов поиска ответа в Интернете я все еще не могу понять, почему мой компонент не выполняет автоматическую повторную визуализацию при изменении свойства @observable.
Я использую Expo для отладки. Я попытался изменить версии в package.json, и я попробовал различные конфигурации для файла .babelrc. Я запустил приложение с помощью response-native run-android cmd - результат все тот же. Я не могу сказать, является ли это ошибкой, у меня нет хорошей конфигурации в package.json, или я все еще не знаю, как использовать Mobx.
Данные с сервера получены, я попытался принудительно выполнить обновление через 5 секунд, и он отображает данные.
Вот мой компонент:
import {inject, observer} from "../../node_modules/mobx-react/native";
@inject('store') @observer
export class MasterView extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
}
componentWillMount() {
if (this.props.store.dataIsFromLocalStorage) {
this.props.store.sync();
}
//setTimeout(()=>this.forceUpdate(), 5000);
}
render() {
return (
<View style={this.props.style}>
{
this.props.store.albums == undefined ?
<ActivityIndicator size="large"/> :
<FlatList data={this.props.store.albums} keyExtractor={(item, index) => item.id.toString()}
renderItem={({item}) => <AlbumMasterView album={item}/>}/>
}
<Button text={""} icon={"add"} onPress={()=>this.props.store.crtSelectedAlbum = Album.emptyAlbum()}
style={{container: styles.addButton}}/>
</View>
);
}
}
Вот магазин:
import {action, observable} from "mobx";
export class Store {
private serverProxy: ServerProxy = serverProxyInstance;
private localStorage: LocalStorage = localStorageInstance;
@observable public albums: Album[] = undefined;
@observable public dataIsFromLocalStorage: boolean = false;
@observable public crtSelectedAlbum: Album = undefined;
constructor() {
this.serverProxy.connectWs(undefined, () => {
this.loadAlbums()
});
this.loadAlbums();
}
private loadAlbums = () => {
this.serverProxy.getAlbums()
.then((albums) => {
this.handleAlbumsHaveArrived(albums);
this.localStorage.clear()
.then(() => this.localStorage.storeAlbums(albums));
this.dataIsFromLocalStorage = false;
})
.catch((error) => {
this.localStorage.getAlbums()
.then((albums) => this.handleAlbumsHaveArrived(albums))
.then(() => this.dataIsFromLocalStorage = true)
.catch(() => Alert.alert("Data load error", "No data could be loaded"));
});
};
@action private handleAlbumsHaveArrived = (albumsAsJs: Album[]) => {
let albums = [];
for (let i = 0; i < albumsAsJs.length; i++) {
albums.push(Album.clone(albumsAsJs[i]));
}
this.albums = albums;
}
Хранение передается следующим компонентам: (AppView содержит MasterView)
render() {
return (
<Provider store={new Store()}>
<AppView/>
</Provider>
);
}
Мой файл package.json
{
"name": "Client_ReactNative2",
"version": "0.0.1",
"private": true,
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject"
},
"dependencies": {
"@babel/plugin-proposal-decorators": "^7.2.3",
"@babel/plugin-transform-react-constant-elements": "^7.2.0",
"@babel/plugin-transform-react-inline-elements": "^7.2.0",
"@types/es6-promise": "^3.3.0",
"@types/react": "16.7.6",
"@types/react-native": "0.57.10",
"@babel/core": "^7.0.0-beta.40",
"@babel/cli": "^7.0.0-beta.40",
"babel-loader": "^8.0.0-beta.0",
"babel-plugin-lodash": "^3.3.2",
"babel-plugin-react-transform": "^3.0.0",
"@babel/preset-react": "^7.0.0-beta.40",
"babel-preset-expo": "^5.0.0",
"expo": "31.0.2",
"mobx": "4.8.0",
"mobx-react": "5.2.3",
"react": "16.6.3",
"react-native": "0.57.8",
"react-native-material-ui": "^1.30.1",
"react-native-vector-icons": "^6.1.0"
},
"devDependencies": {
"@babel/plugin-proposal-decorators": "^7.2.3",
"@babel/preset-flow": "^7.0.0",
"@types/react": "16.7.6",
"@types/react-native": "0.57.10",
"babel-preset-expo": "^5.0.0"
}
}
.babelrc
{
"presets": ["babel-preset-expo"],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }]
]
}
Ожидаемое поведение: метод MasterView.render () вызывается после установки альбомов свойств в вызове метода Store.handleAlbumsHaveArrived ().
Фактические результаты: повторного рендеринга не происходит