Redux状态更改不会更新循环中的组件

时间:2018-11-01 14:28:46

标签: react-native react-redux

我正在创建一个带有同步屏幕的应用程序(反应本机)。由于需要将许多产品导入本地数据库,因此此同步将花费一些时间。因为我想让用户显示该应用程序仍在运行,所以我尝试实现一个进度条,该进度条应随整个过程的百分比而增加。

我尝试使用Redux进行此操作,因为同步不在组件内。

./ App.js

import React from 'react';
import {AppRegistry} from 'react-native';
import {Provider} from 'react-redux';
import Synchronize from "./src/layouts/Synchronize";
import {store} from "./src/store";

class RSCApp extends React.Component {

    render() {
        return (
            <Provider store={store}>
                <Synchronize/>
            </Provider>
        );
    }
}

AppRegistry.registerComponent('RSCApp', () => RSCApp);

export default RSCApp;

./ src / layouts / Synchronize.js

import React from "react";
import {Container, H3} from "native-base";
import {connect} from 'react-redux';
import Sync from "../helpers/Sync";
import {changeCurrentTask, changeCurrentTaskPercent, finishSynchronisation, changeOveralPercent} from "../actions";
import {ImageBackground, StatusBar, Text, View} from "react-native";
import * as Progress from 'react-native-progress';
import synchronizeStyle from "./styles/synchronizeStyle";
import SplashScreen from "react-native-splash-screen";

const launchscreenBg = require("../../assets/launchscreen-bg.png");
const launchscreenLogo = require("../../assets/wolky_300x300.png");

class Synchronize extends React.Component {

    componentDidMount() {
        SplashScreen.hide();

        Sync.openApp();
    }

    render() {
        return (
            <Container>
                <StatusBar barStyle="light-content"/>
                <ImageBackground source={launchscreenBg} style={synchronizeStyle.imageContainer}>
                    <View style={synchronizeStyle.logoContainer}>
                        <ImageBackground source={launchscreenLogo} style={synchronizeStyle.logo}/>
                    </View>
                    <View
                        style={{
                            alignItems: "center",
                            marginBottom: 150,
                            backgroundColor: "transparent"
                        }}
                    >
                        <H3 style={synchronizeStyle.text}>Synchroniseren data</H3>
                        <View style={{marginTop: 8}}/>
                        <Progress.Bar progress={this.props.totalPercent} width={300} height={10} useNativeDriver={true} color={'white'}/>
                        <View style={{marginTop: 8}}/>

                        <Text style={synchronizeStyle.text}>{this.props.taskAction}</Text>
                        <View style={{marginTop: 8}}/>
                        <Progress.Bar progress={this.props.taskPercent} width={300} height={10}
                                      useNativeDriver={true} color={'white'}/>
                    </View>
                </ImageBackground>
            </Container>
        );
    }
}

const mapStateToProps = state => ({
        totalPercent: state.synchronize.totalPercent,
        taskAction: state.synchronize.taskAction,
        taskPercent: state.synchronize.taskPercent,
});

const mapDispatchToProps = {
    changeCurrentTask,
    changeCurrentTaskPercent,
    finishSynchronisation,
    changeOveralPercent
};

export default connect(mapStateToProps, mapDispatchToProps)(Synchronize);

./ src / helpers / Sync.js

import Shops from "../models/Shops";
import {changeCurrent, changeOveralPercent} from "../actions";
import watch from 'redux-watch'
import {store} from "../store";
import Products from "../models/Products";

const Sync = {
    openApp: function () {
        console.log('Synchronize.openAPP fired');

        store.dispatch(changeOveralPercent(0));

        let currentAction = 0;
        let numberOfActions = 2;
        let percentPerAction = (100 / numberOfActions) / 100;





        Shops
            .sync();

    },

    finishedSync: function () {
        alert('The synchronisation finished!');
    }
};

export default Sync;

./ src / models / Shops.js

import API from "../helpers/API";
import {SHOPS_SCHEMA} from "../database/Schemas";
import Database from "../database/Database";
import {store} from "../store";
import {changeCurrentTask, changeCurrentTaskPercent} from "../actions";

const Shops = {
    /** Get all available shops! **/
    all: function () {
        let db = Database.open();
        db.then(realm => {
            console.log(realm.objects(SHOPS_SCHEMA));
        });
    },

    /**
     * Synchronize the shops
     * and store them in the database!
     */
    sync: async function () {
        let realmDB = Database.open();

        store.dispatch(changeCurrentTask('Importeren van beschikbare producten'));
        store.dispatch(changeCurrentTaskPercent(0));

        return API.getShops().then((shops) => {
            console.log(shops);
            if (shops.length > 0) {
                let numberOfShops = shops.length;
                let percentOfOneShop = (100 / numberOfShops) / 100;

                // In this case we are sure we received new shops
                // We can safely delete the content in the database!
                realmDB.then(realm => {
                    const allShops = realm.objects(SHOPS_SCHEMA);
                    console.log('Before delete: ' + allShops.length);

                    if (allShops.length > 0) {
                        console.log('Need to delete the shops!');
                        realm.write(() => {
                            realm.delete(allShops);
                        });
                    }

                    console.log('After delete: ' + allShops.length);

                    if (allShops.length === 0) {
                        console.log('Going to create ' + shops.length + ' shops');

                        // Database is cleared;
                        // insert the new shops!
                        let currentShop = 1;
                        realm.write(() => {
                            shops.map((obj) => {
                                if (realm.objects(SHOPS_SCHEMA).filtered('ShopID=' + obj.id).length === 0) {
                                    console.log('Creating Shop ' + obj.name + ' with ID ' + obj.id);

                                    store.dispatch(changeCurrentTask('[' + currentShop + '/' + numberOfShops + '] Importeren van beschikbare producten'));
                                    store.dispatch(changeCurrentTaskPercent(currentShop * percentOfOneShop));


                                    realm.create(SHOPS_SCHEMA, {
                                        ShopID: obj.id,
                                        ShopName: obj.name
                                    });


                                    currentShop++;
                                }
                            })
                        });

                        console.log('Finished creating shops!');
                    }
                });
            } else {
                // @todo What to do here?
                alert('Could not fetch the right shops!');
            }
        });
    }
};

export default Shops;

所以现在问题出在Shops.js里面,我有一个循环,在这里尝试用新百分比增加进度条。那是行不通的。

唯一可行的方法(也在Shops.js中)是:

store.dispatch(changeCurrentTask('Importeren van beschikbare producten')); store.dispatch(changeCurrentTaskPercent(0));

它显示了正在处理的最新商店: [11/11] Importeren van beschikbare product

最后一步之前的所有内容都无法购买。我很确定这与异步有关,但我不知道如何解决此问题。

也许有人有个好主意?

0 个答案:

没有答案