Почему изменение свойства @observable не вызывает повторную визуализацию компонента? - PullRequest
0 голосов
/ 13 января 2019

Я пытаюсь сделать домашнее задание в 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 ().

Фактические результаты: повторного рендеринга не происходит

1 Ответ

0 голосов
/ 13 января 2019

Мне удалось заставить это работать, изменив это в package.json> зависимости:

"mobx": "4.8.0",
"mobx-react": "5.2.3",

с этим:

"mobx": "3.2.1",
"mobx-react": "4.2.2",

Mobx прост в использовании, но, насколько я могу судить, у него много ошибочных версий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...