如何预处理 React Native 组件获取的 redux 数据?



我有一个用expo构建的react-native应用程序。

这是一个预算应用程序。我正在尝试显示给定月份支出类型的饼图。

我的逻辑如下:

  • 通过 dispatch(( in useEffect 从 redux 检索支出
  • 将支出与其他字段一起推送到将提供给饼图的数组。
  • 以该数组作为道具供应到饼图。

我正在经历什么:

  • 使用 中通过 dispatch(( 从 redux 检索支出效果
  • 尝试将其他字段的支出推送到数据数组。
  • 尝试将此数组提供给饼图。
  • 饼图呈现为完全空白。(此时记录数组显示它也为空(
  • (在 useEffect 钩子中记录数组显示非空数组(

我的代码:

import React, {useEffect} from 'react';
import { StyleSheet, StatusBar, View, Text, AsyncStorage, Button, Dimensions } from 'react-native';
import {useSelector,useDispatch} from 'react-redux';
import {getExp, clearExp} from './../actions/expActions.js';
import _uniqueId from 'lodash/uniqueId';
import { getRecurrExp } from '../actions/recurrExpActions.js';
import { PieChart } from "react-native-chart-kit";
export default function Report() {
const expR = useSelector(state => state.expR)
const recurrExpR = useSelector(state => state.recurrExpR)
const dispatch = useDispatch();
const screenWidth = Dimensions.get("window").width
const chartConfig ={
backgroundColor: "#e26a00",
backgroundGradientFrom: "#fb8c00",
backgroundGradientTo: "#ffa726",
decimalPlaces: 2, // optional, defaults to 2dp
color: (opacity = 1) => `rgba(255, 255, 255, ${opacity})`,
labelColor: (opacity = 1) => `rgba(255, 255, 255, ${opacity})`,
style: {
borderRadius: 16
},
propsForDots: {
r: "6",
strokeWidth: "2",
stroke: "#ffa726"
}
}
var piePieces = [];
const getAllExps = () => {
dispatch(getExp())
dispatch(getRecurrExp())
}
useEffect(() => {
getAllExps()
expR.catCounts.map(cat => {
piePieces.push({value: cat.count / expR.cat * 100, name: cat.category, color: cat.category==="cat1" ? '#E38627' : '#C13C37' })
})
console.log(piePieces) //Log's a filled array
},[])
// Deprecated, saving for 
const clearAsyncStorage = async() => {
AsyncStorage.clear()
}
const clearExpTest = () => {
dispatch(clearExp())
}
return (
<View style={styles.main}>
<View style={styles.container}>
<StatusBar hidden />
{
<PieChart
data={piePieces}
width={220}
height={220}
chartConfig={chartConfig}
accessor="value"
backgroundColor="transparent"
paddingLeft="15"
absolute
/>
}
{console.log(piePieces)} //Logs []
</View>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
backgroundColor: '#ffffe6',
},
main: {
flex: 1,
}
});

我的猜测是这与重新渲染组件有关。由于您正在推送到piePieces而不是重新分配,因此不会重新渲染。

我还建议使用Sate for piePieces来规避这个确切的问题。

将 useState 添加到导入

import React, {useEffect, useState} from 'react';

组件顶部定义饼图件

const [piePieces, setPiePiecse] = useState([]);

您可以使用forEach而不是map因为 map 返回一个包含返回值的新数组

expR.catCounts.forEach(cat => {
setPiePieces([...piePieces, {value: cat.count / expR.cat * 100, name: cat.category, color: cat.category==="cat1" ? '#E38627' : '#C13C37' }])
})

对于将来的任何人,Bloatlords 的答案是正确的,但会导致在每个循环中设置状态的异步问题。

为了解决这个问题,设置状态的正确方法是:

setPiePieces(piePieces => [...piePieces, {value: ((cat.count / expR.cat) * 100),
name: cat.category,
color: (cat.category.localeCompare("cat1") ? "green" : "yellow"),
legendFontColor: "black", legendFontSize: 15}
])

相关内容

  • 没有找到相关文章

最新更新