如何在React Material-table中添加自定义列实现行数据保存至MongoDB
实现步骤及修改代码
前端部分修改
你不需要修改接口返回的原始数据,Material-Table的列配置支持自定义渲染,直接新增操作列即可,修改后的前端代码如下:
import React, {useState, useEffect} from 'react' import MaterialTable from 'material-table' import axios from "axios"; const DataTable = () => { const [tableData, setTableData] = useState([]); const [showMyStocks, setShowMyStocks] = useState(false); const [myStocks, setMyStocks] = useState([]); const columns = [ {title: 'NAME', field: 'name', width: 200}, {title: 'SYMBOL', field: 'symbol', width: 200}, {title: 'MARKET CAP', field: 'market_cap', width: 200}, {title: 'CURRENT PRICE', field: 'price', width: 200}, // 新增自定义操作列,不需要修改原接口数据 { title: '操作', width: 150, render: rowData => <button onClick={() => handleSave(rowData)}>保存到自选</button> } ] // 保存股票到后端接口 const handleSave = async (rowData) => { try { // 按需提取要存储的字段,避免冗余 const saveData = { name: rowData.name, symbol: rowData.symbol, market_cap: rowData.market_cap, price: rowData.price } await axios.post('/api/stocks/save', saveData) alert('保存成功') } catch (err) { console.error('保存失败', err) // 重复保存的提示可以根据后端返回的错误码自定义 alert(err.response?.data?.msg || '保存失败,请重试') } } // 获取已保存的自选股票 const fetchMyStocks = async () => { const res = await axios.get('/api/stocks/my') setMyStocks(res.data) setShowMyStocks(true) } useEffect(() => { axios .get( "https://api.nomics.com/v1/currencies/ticker?key=xyz&interval=1d,30d&convert=USD&per-page=100" ) .then((res) => { console.log(res); setTableData(res.data); }) }, []); return ( <div> <button onClick={fetchMyStocks} style={{margin: '20px 14%'}}>查看我的自选股票</button> <div > <MaterialTable style={{height: 400, width: '70%', left: '14%', top: 20}} data={tableData} columns={columns} title={"Stock Details Table"} options={{ search: true }} /> </div> {/* 自选股票弹窗,也可以单独做页面展示 */} {showMyStocks && ( <div style={{position: 'fixed', top: '10%', left: '10%', width: '80%', background: '#fff', padding: '20px', boxShadow: '0 0 10px #ccc'}}> <button onClick={() => setShowMyStocks(false)} style={{float: 'right'}}>关闭</button> <MaterialTable data={myStocks} columns={columns.slice(0,4)} // 复用原有列配置,去掉操作列 title={"我的自选股票"} /> </div> )} </div> ) } export default DataTable
后端MERN接口实现
1. 定义MongoDB数据模型
新建models/Stock.js文件,定义股票存储结构:
const mongoose = require('mongoose') const stockSchema = new mongoose.Schema({ name: String, // 加唯一索引避免重复保存同一只股票 symbol: { type: String, unique: true }, market_cap: Number, price: Number, saveTime: { type: Date, default: Date.now } }) module.exports = mongoose.model('Stock', stockSchema)
2. 编写接口路由
新建routes/stocks.js文件,编写两个接口:
const express = require('express') const router = express.Router() const Stock = require('../models/Stock') // 保存自选股票接口 router.post('/save', async (req, res) => { try { const stock = new Stock(req.body) await stock.save() res.status(200).json({ code: 0, msg: '保存成功' }) } catch (err) { if (err.code === 11000) { return res.status(400).json({ code: 1, msg: '该股票已在自选列表中' }) } res.status(500).json({ code: 1, msg: '保存失败' }) } }) // 获取所有已保存自选股票接口 router.get('/my', async (req, res) => { const stocks = await Stock.find().sort({ saveTime: -1 }) res.status(200).json(stocks) }) module.exports = router
3. 挂载路由
在后端入口文件中挂载路由,确保和前端请求的地址匹配:
// 要提前完成MongoDB连接配置 app.use('/api/stocks', require('./routes/stocks'))
内容的提问来源于stack exchange,提问作者Leo
相关产品推荐
相关产品推荐

