我正在创建一个带有同步屏幕的应用程序(反应本机)。由于需要将许多产品导入本地数据库,因此此同步将花费一些时间。因为我想让用户显示该应用程序仍在运行,所以我尝试实现一个进度条,该进度条应随整个过程的百分比而增加。
我尝试使用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
最后一步之前的所有内容都无法购买。我很确定这与异步有关,但我不知道如何解决此问题。
也许有人有个好主意?