Javascript 如何预处理React本机组件获取的redux数据?
我有一个用expo构建的react本机应用程序 这是一个预算应用程序。我试图显示给定月份支出类型的饼图 我的逻辑如下:Javascript 如何预处理React本机组件获取的redux数据?,javascript,reactjs,react-native,mobile,Javascript,Reactjs,React Native,Mobile,我有一个用expo构建的react本机应用程序 这是一个预算应用程序。我试图显示给定月份支出类型的饼图 我的逻辑如下: 通过useEffect中的dispatch()从redux检索支出 将支出和其他字段一起推送到将提供给饼图的数组中 将该数组作为道具提供给饼图 我所经历的: 通过useEffect中的dispatch()从redux检索支出 尝试将带有其他字段的支出推送到数据数组 尝试将此数组提供给饼图 饼图显示为完全空白。(此时记录数组也会显示为空) (将数组记录在useEffect钩
- 通过useEffect中的dispatch()从redux检索支出
- 将支出和其他字段一起推送到将提供给饼图的数组中
- 将该数组作为道具提供给饼图
- 通过useEffect中的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,
}
});
import React,{useffect}来自“React”;
从“react native”导入{样式表、状态栏、视图、文本、异步存储、按钮、维度};
从“react-redux”导入{useSelector,useDispatch};
从“/../actions/expActions.js”导入{getExp,clearExp};
从“lodash/uniqueId”导入“uniqueId”;
从“../actions/recurrExpActions.js”导入{getRecurrExp};
从“react native chart kit”导入{PieChart};
导出默认函数报告(){
const expR=useSelector(state=>state.expR)
const recurrExpR=useSelector(state=>state.recurrExpR)
const dispatch=usedpatch();
const screenWidth=维度.get(“窗口”).width
常量图表配置={
背景颜色:“e26a00”,
背景梯度来自:“fb8c00”,
背景梯度至:“ffa726”,
小数点:2,//可选,默认为2dp
颜色:(不透明度=1)=>`rgba(255,255,255,${opacity})`,
labelColor:(不透明度=1)=>`rgba(255,255,255,${opacity})`,
风格:{
边界半径:16
},
道具:{
r:“6”,
冲程宽度:“2”,
笔划:“ffa726”
}
}
var Piepices=[];
常量getAllExps=()=>{
调度(getExp())
分派(getRecurrExp())
}
useffect(()=>{
getAllExps()
expR.catCounts.map(cat=>{
Piecipes.push({value:cat.count/expR.cat*100,name:cat.category,color:cat.category==“cat1”?“#E38627':”#C13C37})
})
console.log(piepeces)//log是一个填充数组
},[])
//不推荐使用,节省时间
常量clearAsyncStorage=async()=>{
AsyncStorage.clear()
}
常量clearExpTest=()=>{
分派(clearExp())
}
返回(
{
}
{console.log(piecipes)}//Logs[]
);
}
const styles=StyleSheet.create({
容器:{
弹性:1,
flexDirection:'列',
为内容辩护:“中心”,
背景颜色:“#ffffe6”,
},
主要内容:{
弹性:1,
}
});
我猜这与重新呈现组件有关。由于您正在推送拼图
,并且没有重新分配,因此不会重新渲染
我还建议使用useSate for Piecipes来避免这个确切的问题
将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的答案都是正确的,但会导致在For-each循环中设置状态的异步问题 要解决此问题,设置状态的正确方法是:
setPiePieces(piePieces => [...piePieces, {value: ((cat.count / expR.cat) * 100),
name: cat.category,
color: (cat.category.localeCompare("cat1") ? "green" : "yellow"),
legendFontColor: "black", legendFontSize: 15}
])
这看起来好像解决了我的问题。然而,饼图组件出现了一个问题。我会尝试用你给我的信息来修复它,并很快确认你的答案是正确的。谢谢你的帮助!饼图数据属性需要一个数组,在实现了您的建议之后,它似乎接收到了一个JS对象。你知道为什么会发生这种情况吗?再看一次setPiePices,我忘了加方括号;)现在应该可以了<代码>设置接口([…接口,{value:cat.count/expR.cat*100,name:cat.category,color:cat.category==“cat1”?“#E38627':“#C13C37”}])解决了一个让我发疯3天的问题。非常感谢。