Изменение состояния Redux не обновляет компонент внутри цикла - PullRequest
0 голосов
/ 01 ноября 2018

Я создаю приложение (реагирует на родную) с экраном синхронизации. Эта синхронизация займет некоторое время, так как необходимо импортировать много продуктов в локальную базу данных. Поскольку я хочу, чтобы пользователь показал, что приложение все еще работает, я пытаюсь реализовать индикатор выполнения, который должен увеличиваться с процентом полного процесса.

Я пытаюсь сделать это с 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 / макеты / 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 / хелперы / 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 / модели / 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)); * 1 033 *

И показывает последний обработанный магазин: [11/11] Importerren van beschikbare producten

Все до последнего шага не идет по магазинам. Я почти уверен, что это как-то связано с асинхронностью, но я не могу понять, как решить эту проблему.

Может, у кого-нибудь есть хорошая идея?

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