如何在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,提问作者Кирилл
相关产品推荐
相关产品推荐

