我正在尝试对图像元数据对象列表执行异步映射。
对于列表中的每个对象,我检查字符串import React, { Component } from 'react';
import IncomeList from './components/IncomeList';
import ExpenseList from './components/ExpenseList';
import AddItem from './components/AddItem';
import Chart from './components/Chart';
import './App.css';
class App extends Component {
constructor(){
super()
this.state = {
incomeItems: [],
expenseItems: [],
totalIncome: 0,
totalExpense: 0,
color: 'black',
incEarned: 0,
incInvest: 0,
incSales: 0,
incRe: 0,
incServices: 0,
incOther: 0,
incEarnedPCT: 0,
incInvestPCT: 0,
incSalesPCT: 0,
incRePCT: 0,
incServicesPCT: 0,
incOtherPCT: 0,
chartData: {}
}
this.addBudgetItem = this.addBudgetItem.bind(this);
this.addExpenseItem = this.addExpenseItem.bind(this);
this.deleteIncomeItem = this.deleteIncomeItem.bind(this);
this.deleteExpenseItem = this.deleteExpenseItem.bind(this);
}
addBudgetItem (item, amount, category) {
let newIncomeTotal = this.state.totalIncome + parseInt(amount);
this.setState(
{
incomeItems: [...this.state.incomeItems, {item: item, amount: amount, category: category}],
totalIncome: newIncomeTotal
}, () => {
const newIncList = this.state.incomeItems;
let incEarned = this.state.incEarned;
let incInvest = this.state.incInvest;
let incSales = this.state.incSales;
let incRe = this.state.incRe;
let incServices = this.state.incServices;
let incOther = this.state.incOther;
let incEarnedPCT = 0;
let incInvestPCT = 0;
let incSalesPCT = 0;
let incRePCT = 0;
let incServicesPCT = 0;
let incOtherPCT = 0;
newIncList.map((item) => {
if(item.category === 'earned'){
incEarned += parseInt(item.amount);
incEarnedPCT = incEarned/parseInt(this.state.totalIncome);
} else if (item.category === 'invest'){
incInvest += parseInt(item.amount);
incInvestPCT = incInvest/parseInt(this.state.totalIncome);
} else if (item.category === 'sales'){
incSales += parseInt(item.amount);
incSalesPCT = incSales/parseInt(this.state.totalIncome);
} else if (item.category === 're'){
incRe += parseInt(item.amount);
incRePCT = incRe/parseInt(this.state.totalIncome);
} else if (item.category === 'services'){
incServices += parseInt(item.amount);
incServicesPCT = incServices/parseInt(this.state.totalIncome);
} else {
incOther += parseInt(item.amount);
incOtherPCT = incOther/parseInt(this.state.totalIncome);
}
})
//let newData = [incEarnedPCT, incInvestPCT, incSalesPCT, incRePCT, incServicesPCT, incOtherPCT];
this.setState({
incEarnedPCT: incEarnedPCT,
incInvestPCT: incInvestPCT,
incSalesPCT: incSalesPCT,
incRePCT: incRePCT,
incServicesPCT: incServicesPCT,
incOtherPCT: incOtherPCT,
chartData: {
labels: ['Earned', 'Investments', 'Sales', 'Real Estate', 'Services', 'Other'],
datasets: [
{
label: 'Income Distribution',
backgroundColor: ['rgba(250,75,185,0.2)', 'rgba(255,99,132,0.2)', 'rgba(255,90,132,0.5)', 'rgba(255,80,110,0.2)', 'rgba(235,75,150,.2)'],
data: [50, 55, 3, 44, 25, 60]
}
]
}
}, () => {
console.log(`Earned: ${incEarned} PCT: ${this.state.incEarnedPCT}\n Invest: ${incInvest} PCT: ${this.state.incInvestPCT}\n Sales: ${incSales} PCT: ${this.state.incSalesPCT}\n Real Estate: ${incRe} PCT: ${this.state.incRePCT}\n Services: ${incServices} PCT: ${this.state.incServicesPCT}\n Other: ${incOther} PCT: ${this.state.incOtherPCT}`);
alert(`CURRENT DATA: ${this.state.chartData.datasets[0].data}`);
})
})
}
addExpenseItem (expItem, expAmount, expCategory) {
let newExpenseTotal = this.state.totalExpense + parseInt(expAmount);
this.setState({
expenseItems: [...this.state.expenseItems, {expItem: expItem, expAmount: expAmount, expCategory: expCategory}],
totalExpense: newExpenseTotal
})
}
deleteIncomeItem (index) {
const newIncList = this.state.incomeItems;
const slicedIncome = newIncList.slice(0, index).concat(newIncList.slice(index + 1));
this.setState({incomeItems: slicedIncome});
let total = 0;
slicedIncome.map((inc) => {total += parseInt(inc.amount)});
this.setState({totalIncome: total});
}
deleteExpenseItem (index) {
const newExpList = this.state.expenseItems;
const slicedExp = newExpList.slice(0, index).concat(newExpList.slice(index + 1));
this.setState({expenseItems: slicedExp});
let total = 0;
slicedExp.map((exp) => {total += parseInt(exp.expAmount)});
this.setState({totalExpense: total});
}
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">Monthly Budget</h1>
</header>
<div className="container">
<AddItem addBudgetItem={this.addBudgetItem} addExpenseItem={this.addExpenseItem}/>
<div className="line"></div>
<div className="UIdiv">
<table>
<h1>INCOME ITEMS</h1>
<tr><IncomeList incomeList={this.state.incomeItems} deleteIncomeItem={this.deleteIncomeItem}/></tr>
<p className="income-desc">Total Income: {this.state.totalIncome}</p>
</table>
<table>
<h1>EXPENSE ITEMS</h1>
<tr><ExpenseList expenseList={this.state.expenseItems} deleteExpenseItem={this.deleteExpenseItem}/></tr>
<p className="expense-desc">Total Expense: {this.state.totalExpense} </p>
</table>
<h2 style={(this.state.totalIncome - this.state.totalExpense === 0) ? {color: 'black'}: (this.state.totalIncome > this.state.totalExpense) ? {color:'green'}:{color:'red'}}> TOTAL BALANCE: {this.state.totalIncome - this.state.totalExpense}</h2>
</div>
</div>
<div>
<Chart chartData={this.state.chartData}/>
</div>
</div>
);
}
}
export default App;
//Child Component - Chart
import React from 'react'
import {Doughnut} from 'react-chartjs-2';
class Chart extends React.Component {
constructor(props){
super(props);
this.state = {
chartData: props.chartData
}
}
render(){
return (
<Doughnut
data={this.state.chartData}
width={100}
height={50}
/>
)
}
}
export default Chart
是否在设备上存在。如果没有,我使用RNFetchBlob和对象的参数device_path
将映像下载到设备。之后,我将对象的download_url
更新为新下载的图像。
执行以下代码时,我的函数device_path
返回checkPaths
。我希望函数返回此值:
{"_40":0,"_65":0,"_55":null,"_72":null}
我应该如何修改我的功能以使其正常工作?
[
{ device_path: 'goodimagepath1', download_url: 'mysecretdownloadurl1' },
{ device_path: 'goodimagepath2', download_url: 'mysecretdownloadurl2' }
];
答案 0 :(得分:0)
由于checkPaths是异步的,因此它返回一个promise。应该在componentDidMount
中进行处理,如下所示:
checkPaths(this.image_references).then(checked_paths => {
console.log("resolved promise", checked_paths)
console.log("checked image paths", JSON.stringify(checked_paths));
}).catch(e => {
console.log("error checking image paths", e)
});
我还修改了功能checkPaths
,以等待检查图像路径并等待下载图像。
如果有更干净的方法可以做到这一点,我就耳熟能详。
import React, { Component } from "react";
import { View, Text } from "react-native";
import RNFetchBlob from "rn-fetch-blob";
async function checkPaths(image_metadata_list) {
const promises = image_metadata_list.map(async (image_metadata, idx) => {
const exists = await RNFetchBlob.fs.exists(image_metadata.device_path)
if (exists === false) {
console.log("image does not exist on device, downloading...");
const dirs = RNFetchBlob.fs.dirs;
const filename = (idx + 1).toString() + '.jpg'
const resp = await RNFetchBlob.config({
path: dirs.DocumentDir + `/user_images/${filename}`
}).fetch('GET', `${image_metadata.download_url}`).progress((received = 0, total = 0) => {
//Handle progress of download here.. May be update UI...\
}).then((resp) => {
// update the device path
image_metadata.device_path = resp.path();
console.log("image path modified", image_metadata);
}).catch(e => {
console.log("error downloading image", e);
})
}
else {
console.log("image path OK", image_metadata);
}
return image_metadata;
})
return await Promise.all(promises);
}
export default class App extends Component {
constructor(props) {
super(props);
this.image_references = [
{ device_path: 'badimagepath1', download_url: 'https://firebasestorage.googleapis.com/v0/b/fivedates-dev.appspot.com/o/user_images%2FoHK9DQ94ZZOBIejbVO8luJZnEU22%2F1.jpg?alt=media&token=6c5e053d-45b4-4ab0-a52b-65c1180624ed' },
{ device_path: 'badimagepath2', download_url: 'https://firebasestorage.googleapis.com/v0/b/fivedates-dev.appspot.com/o/user_images%2FoHK9DQ94ZZOBIejbVO8luJZnEU22%2F1.jpg?alt=media&token=6c5e053d-45b4-4ab0-a52b-65c1180624ed' }
];
}
componentDidMount() {
console.log("component mounted");
console.log("checking image paths", JSON.stringify(this.image_references));
checkPaths(this.image_references).then(checked_paths => {
console.log("resolved promise", checked_paths)
console.log("checked image paths", JSON.stringify(checked_paths));
}).catch(e => {
console.log("error checking image paths", e)
});
}
render() {
return (
<View style={{ flex: 1 }}>
<Text>Welcome to MWE</Text>
</View>
)
}
}