React项目生成Nivo饼图时持续出现N.map is not a function错误求助
解决React中Nivo饼图的"N.map is not a function"错误
问题描述
在React项目中尝试生成Nivo饼图,控制台日志确认finalData是包含饼图所需信息的数组,但始终出现"N.map is not a function"错误,无法正常渲染饼图。以下是涉及的两个组件代码:
Pie组件
import { Box } from "@mui/material"; import Header from "../components/Header"; import PieChart from "../components/PieChart"; import { useEffect, useState } from "react"; import { mockDistrictData } from "../data/MockData"; const Pie = () => { const [districts, setDistricts] = useState([]); const [selectedDistrict, setSelectedDistrict] = useState(''); const [finalData, setFinalData] = useState([]); const lightGreenColor = "hsl(154,52%,45%)"; const greenColor = "hsl(139,100%,83%)"; const [isGeneratingChart, setIsGeneratingChart] = useState(false); // Fetch data for mechanical bikes const fetchMechanicalBikes = (districtName) => { const url = `http://localhost:8800/station_status/bikes/mechanical/${districtName}`; return fetch(url) .then(response => response.json()) .then(data => { // Transform the fetched data and assign random colors return data.map(i => ({ id: `Mechanical bikes`, label: `Mechanical bikes`, value: i.value, color: lightGreenColor })); }); }; // Fetch data for electronic bikes const fetchElectronicBikes = (districtName) => { const url = `http://localhost:8800/station_status/bikes/electric/${districtName}`; return fetch(url) .then(response => response.json()) .then(data => { // Transform the fetched data and assign random colors return data.map(item => ({ id: `Electronic bikes`, label: `Electronic bikes`, value: item.value, color: greenColor })); }); }; // Combine the fetched data for mechanical and electronic bikes const combineFetchedData = async (districtName) => { try { setIsGeneratingChart(true); // Set the flag to indicate chart generation in progress const mechanicalData = await fetchMechanicalBikes(districtName); const electronicData = await fetchElectronicBikes(districtName); // Combine the two arrays into a single array const combinedData = [...mechanicalData, ...electronicData]; setTimeout(() => { setFinalData(combinedData); console.log(combinedData); // Print the combined data setIsGeneratingChart(false); // Set the flag to indicate chart generation completed }, 3000); // 3 seconds delay // You can use the combined data for further processing or visualization } catch (error) { console.error('Error fetching data: ', error); setIsGeneratingChart(false); // Set the flag to indicate chart generation completed with an error } }; useEffect(() => { // Fetch districts const fetchDistricts = () => { setDistricts(mockDistrictData.map(district => district.district_name)); }; fetchDistricts(); }, []); return ( <Box m="20px"> <Header title="Pie Chart" subtitle="Electric Bikes & Mechanical Bikes" /> <Box height="75vh"> <div> <select value={selectedDistrict} onChange={e => setSelectedDistrict(e.target.value)}> <option value="">Select a district</option> {districts.map(district => ( <option key={district} value={district}>{district}</option> ))} </select> <button disabled={isGeneratingChart} onClick={() => combineFetchedData(selectedDistrict)}> {isGeneratingChart ? 'Generating...' : 'Generate Chart'} </button> </div> {finalData.length > 0 && <PieChart data={finalData} />} </Box> </Box> ); }; export default Pie;
原始PieChart组件
import { ResponsivePie } from "@nivo/pie"; import { tokens } from "../theme"; import { useTheme } from "@mui/material"; const PieChart = (finalData) => { const theme = useTheme(); const colors = tokens(theme.palette.mode); return ( <ResponsivePie data={finalData} // ...其他配置 /> ); }; export default PieChart;
错误原因
PieChart组件的参数接收逻辑错误:React组件的第一个参数是props对象,而非直接传入的data属性。当前代码中finalData实际是包含data字段的props对象,而非数组,导致Nivo的ResponsivePie组件尝试对对象调用map方法,从而抛出错误。
修复方案
修改PieChart组件的参数接收方式,解构出data属性,或者通过props.data获取数组:
修改后的PieChart组件
import { ResponsivePie } from "@nivo/pie"; import { tokens } from "../theme"; import { useTheme } from "@mui/material"; // 解构props获取data const PieChart = ({ data }) => { const theme = useTheme(); const colors = tokens(theme.palette.mode); return ( <ResponsivePie data={data} theme={{ axis: { domain: { line: { stroke: colors.grey[100], }, }, legend: { text: { fill: colors.grey[100], }, }, ticks: { line: { stroke: colors.grey[100], strokeWidth: 1, }, text: { fill: colors.grey[100], }, }, }, legends: { text: { fill: colors.grey[100], }, }, }} margin={{ top: 40, right: 80, bottom: 80, left: 80 }} innerRadius={0.5} padAngle={0.7} cornerRadius={3} activeOuterRadiusOffset={8} borderColor={{ from: "color", modifiers: [["darker", 0.2]], }} arcLinkLabelsSkipAngle={10} arcLinkLabelsTextColor={colors.grey[100]} arcLinkLabelsThickness={2} arcLinkLabelsColor={{ from: "color" }} enableArcLabels={false} arcLabelsRadiusOffset={0.4} arcLabelsSkipAngle={7} arcLabelsTextColor={{ from: "color", modifiers: [["darker", 2]], }} defs={[ { id: "dots", type: "patternDots", background: "inherit", color: "rgba(255, 255, 255, 0.3)", size: 4, padding: 1, stagger: true, }, { id: "lines", type: "patternLines", background: "inherit", color: "rgba(255, 255, 255, 0.3)", rotation: -45, lineWidth: 6, spacing: 10, }, ]} legends={[ { anchor: "bottom", direction: "row", justify: false, translateX: 0, translateY: 56, itemsSpacing: 0, itemWidth: 100, itemHeight: 18, itemTextColor: "#999", itemDirection: "left-to-right", itemOpacity: 1, symbolSize: 18, symbolShape: "circle", effects: [ { on: "hover", style: { itemTextColor: "#000", }, }, ], }, ]} /> ); }; export default PieChart;
或者也可以选择另一种写法:
const PieChart = (props) => { const theme = useTheme(); const colors = tokens(theme.palette.mode); return ( <ResponsivePie data={props.data} // ...其他配置 /> ); };
验证
修改后,ResponsivePie将接收到正确的数组类型数据,即可正常渲染饼图,不会再出现map is not a function错误。
内容的提问来源于stack exchange,提问作者user19292442
相关产品推荐
相关产品推荐

