You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ChartJS中展示MongoDB最新Post数据?解决值为undefined问题

问题解决步骤

1. 修复环形图组件的Props接收逻辑

React组件的参数是props对象,你当前直接把props当成post传入,导致post.title无法找到对应值,出现undefined。修改组件代码:

// 解构props中的post属性
const DoughnutChartComponent = ({ post }) => {
  // 增加空值判断,避免post为undefined时报错
  const Ferum = post && !isNaN(parseInt(post.title)) ? parseInt(post.title) : 0;
  const Sulfur = post && !isNaN(parseInt(post.text)) ? parseInt(post.text) : 0;
  
  console.log('post.title:', post?.title);
  console.log('post.text:', post?.text);
  console.log('Переменные', Ferum, Sulfur);
  
  const Other = 100 - (Ferum + Sulfur);
  
  const data = {
    datasets: [{
      data: [Ferum, Sulfur, Other],
      backgroundColor: [
        '#F7BA4E',
        '#D9D9D9',
        '#12191F',
      ],
      border: false,
      borderRadius: 3,
    }]
  };

  const options = {
    cutout: 60,
    responsive: true,
  };
  
  return <Doughnut data={data} options={options} />;
};

2. 在页面组件中获取Redux里的最新Post数据

你当前只实现了提交Post的逻辑,但没有从Redux读取已有的Post数据。添加useSelector获取Post列表,并筛选出最新的一条:

import React, { useState } from 'react'
import { DoughnutChartComponent as Doughnut } from "../components/Chart.jsx"
import { useDispatch, useSelector } from 'react-redux' // 导入useSelector
import { createPost } from '../../redux/features/post/postSlice.js'

export const OreComposition = () => {
  const [title, setTitle] = useState('')
  const [text, setText] = useState('')
  const [image, setImage] = useState('')

  const dispatch = useDispatch()
  // 从Redux获取posts列表,假设你的postSlice中state结构是{ posts: [] }
  const posts = useSelector(state => state.post.posts || [])
  
  // 按createdAt倒序排序,取第一条作为最新post
  const latestPost = posts.length > 0 
    ? [...posts].sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt))[0]
    : null

  const submitHandler = () => {
    try {
      const data = new FormData()
      data.append('title', title)
      data.append('text', text)
      
      dispatch(createPost(data))
      // 提交后清空输入框
      setTitle('')
      setText('')
    } catch (error) {
      console.log(error)
    }
  }

  return (
    <div className='add-title h-screen flex justify-around items-center text-center ml-[246px]'>
      <div className='bg-[#313d44] rounded-lg py-3 px-10 w-50'>
        <form onSubmit={e => e.preventDefault()} className='mt-10 w-40 h-50 '>
          <h1 className='w-40 text-lg text-white text-center'>Ore composition</h1>
          <input
            value={image}
            onChange={e => setImage(e.target.value)}
            type="file"
            style={{display: 'none'}}/>
          <label className='text-xs text-[white] text-left'>
            Ferum:
            <input
              max="99"
              type="number"
              value={title}
              onChange={e => setTitle(e.target.value)}
              placeholder='Ferum persentage'
              className='mt-1 text-white w-full rounded-lg bg-[#12191F] py-1 px-2'/>
          </label>
          <label className='text-xs text-white'>
            Sulfur:
            <input
              max="99"
              type="number"
              value={text}
              onChange={e => setText(e.target.value)}
              placeholder='Sulfur persentage'
              className='mt-1 text-white w-full rounded-lg bg-[#12191F] py-1 px-2'/>
          </label>
          <div className='flex gap-8 justify-center mt-4'>
            <button
              onClick={submitHandler}
              className='bg-[#12191F] flex justify-center items-center text-xs text-white rounded-lg py-2 px-4'
            >
              Submit
            </button>
          </div>
        </form>
      </div>
      <div className="chart-box  h-80 w-80">
        {/* 传递最新post给环形图组件 */}
        <Doughnut post={latestPost} />
      </div>
    </div>
  )
} 

3. 验证Redux状态存储逻辑

确保你的postSlice中正确将新创建的Post添加到列表中,示例如下:

// postSlice.js示例
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import axios from 'axios'

export const createPost = createAsyncThunk(
  'post/createPost',
  async (formData) => {
    const response = await axios.post('/api/posts', formData)
    return response.data
  }
)

const postSlice = createSlice({
  name: 'post',
  initialState: {
    posts: [],
    loading: false,
    error: null
  },
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(createPost.fulfilled, (state, action) => {
        // 将新post添加到数组开头,保证最新的在最前面
        state.posts.unshift(action.payload)
      })
  }
})

export default postSlice.reducer

关键问题总结

  • 组件props接收错误:未正确解构props对象,导致无法读取post属性
  • 未从Redux获取数据:页面组件未读取已存储的posts,无法传递数据给环形图
  • 缺少空值判断:当没有post数据时,未做默认值处理,导致parseInt报错

内容的提问来源于stack exchange,提问作者Кирилл

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 18:55:53