为什么@observable属性更改不会触发组件重新渲染?

时间:2019-01-13 00:32:23

标签: typescript react-native mobx mobx-react

我正在尝试使用Android的React-Native,TypeScript和Mobx做一个家庭作业项目。经过5个多小时的互联网搜索答案后,我仍然无法弄清楚为什么@observable属性更改时我的组件不能自动重新渲染。

我正在使用Expo进行调试。我试过更改package.json中的版本,并尝试了.babelrc文件的不同配置。我使用react-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 }]
  ]
}

预期的行为:在Store.handleAlbumsHaveArrived()方法调用中设置属性相册后调用MasterView.render()方法。

实际结果:重新渲染不会发生

1 个答案:

答案 0 :(得分:0)

我已经设法通过在package.json>依赖项中进行更改来使其起作用:

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

与此:

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

据我所知,Mobx易于使用,但有很多错误版本。

相关问题