【问题标题】:How to preprocess fetched redux data for a React Native component?如何为 React Native 组件预处理获取的 redux 数据?
【发布时间】:2020-05-20 21:15:44
【问题描述】:

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

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

我的逻辑如下:

  • 通过 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,
  }
});

【问题讨论】:

    标签: javascript reactjs react-native mobile


    【解决方案1】:

    我的猜测是这与重新渲染组件有关。由于您正在推动 piePieces 并且不重新分配它不会重新渲染。

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

    将 useState 添加到您的导入中

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

    你的组件顶部定义piePieces

    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' }])
    })
    

    【讨论】:

    • 这看起来可能已经解决了我的问题。然而,它引起了饼图组件的问题。我将尝试使用您提供给我的信息来修复它,并会尽快确认您的答案是正确的。感谢您的帮助!
    • 饼图数据道具需要一个数组,已经实现了您的建议,它似乎正在接收一个 JS 对象。任何想法为什么会发生这种情况?
    • 再看看 setPiePices,我忘了加方括号 ;) 现在应该可以了。 setPiePieces([...piePieces, {value: cat.count / expR.cat * 100, name: cat.category, color: cat.category==="cat1" ? '#E38627' : '#C13C37' }])
    • 解决了一个困扰我大约 3 天的问题。谢谢!!
    【解决方案2】:

    对于未来的任何人,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}
    ])
    

    【讨论】:

      猜你喜欢
      • 2018-07-10
      • 1970-01-01
      • 2020-11-05
      • 2019-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-07
      相关资源
      最近更新 更多