我做了一个小项目,需要一个csv文件,并上传它。然后处理其内容以填充mongodb集合
我犯了这两个错误:
在VS代码控制台中:
API resolved without sending a response for /api/upload, this may result in stalled requests.
在Web App中:
Unhandled Runtime Error
Error: Objects are not valid as a React child (found: object with keys {storageErrors}). If you meant to render a collection of children, use an array instead.
Call Stack
throwOnInvalidObjectType
node_modules\react-dom\cjs\react-dom.development.js (14887:0)
createChild
node_modules\react-dom\cjs\react-dom.development.js (15139:0)
reconcileChildrenArray
node_modules\react-dom\cjs\react-dom.development.js (15404:0)
reconcileChildFibers
node_modules\react-dom\cjs\react-dom.development.js (15821:0)
reconcileChildren
node_modules\react-dom\cjs\react-dom.development.js (19167:0)
updateHostComponent
node_modules\react-dom\cjs\react-dom.development.js (19924:0)
beginWork
node_modules\react-dom\cjs\react-dom.development.js (21618:0)
HTMLUnknownElement.callCallback
node_modules\react-dom\cjs\react-dom.development.js (4164:0)
Object.invokeGuardedCallbackDev
node_modules\react-dom\cjs\react-dom.development.js (4213:0)
invokeGuardedCallback
node_modules\react-dom\cjs\react-dom.development.js (4277:0)
beginWork$1
node_modules\react-dom\cjs\react-dom.development.js (27451:0)
performUnitOfWork
node_modules\react-dom\cjs\react-dom.development.js (26557:0)
workLoopSync
node_modules\react-dom\cjs\react-dom.development.js (26466:0)
renderRootSync
node_modules\react-dom\cjs\react-dom.development.js (26434:0)
performConcurrentWorkOnRoot
node_modules\react-dom\cjs\react-dom.development.js (25738:0)
workLoop
node_modules\scheduler\cjs\scheduler.development.js (266:0)
flushWork
node_modules\scheduler\cjs\scheduler.development.js (239:0)
MessagePort.performWorkUntilDeadline
node_modules\scheduler\cjs\scheduler.development.js (533:0)
这是我在Nextjs中的前端和API代码:
前端
import { useState } from 'react';
const IndexPage = () => {
const [selectedFile, setSelectedFile] = useState(null);
const [uploading, setUploading] = useState(false);
const [message, setMessage] = useState(null);
const [error, setError] = useState(null);
const handleFileChange = (event) => {
setSelectedFile(event.target.files[0]);
};
const handleFileUpload = async () => {
if (!selectedFile) {
setError('Please select a file');
return;
}
setError(null);
setMessage(null);
setUploading(true);
const formData = new FormData();
formData.append('file', selectedFile);
try {
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
});
const data = await response.json();
if (response.ok) {
setMessage(data.message);
} else {
setError(data.error);
}
} catch (error) {
setError('Something went wrong');
} finally {
setUploading(false);
}
};
return (
<div>
<h1>File Upload</h1>
<input
name="file"
type="file"
accept=".csv"
onChange={handleFileChange}
/>
<button
onClick={handleFileUpload}
disabled={uploading}
>
{uploading ? 'Uploading...' : 'Upload'}
</button>
{message && <p>{message}</p>}
{error && <p>Error: {error}</p>}
</div>
);
};
export default IndexPage;
这是后端
// pages/api/upload.js
import multer from 'multer';
import csv from 'csv-parser';
import fs from 'fs';
import { MongoClient, ObjectId } from 'mongodb';
const upload = multer({
dest: 'uploads/', // Directory to store uploaded files
limits: {
fileSize: 5 * 1024 * 1024, // Limit file size to 5MB
},
fileFilter: (req, file, cb) => {
if (file.mimetype !== 'text/csv') {
cb(new Error('Only CSV files are allowed'));
} else {
cb(null, true);
}
},
});
const saveDistinctValues = async (collectionName, distinctValues) => {
const client = new MongoClient('mongodb://0.0.0.0:27017/testcsv');
try {
await client.connect();
const db = client.db();
const collection = db.collection(collectionName);
await collection.insertMany(distinctValues.map((value) => ({ value })));
} finally {
await client.close();
}
};
const establishRelationships = async () => {
const client = new MongoClient(process.env.MONGODB_URI);
try {
await client.connect();
const db = client.db();
const masterCategoryCollection = db.collection('master_category');
const subCategoryCollection = db.collection('sub_category');
const productGroupCollection = db.collection('product_group');
const productCollection = db.collection('product');
const masterCategories = await masterCategoryCollection.find().toArray();
for (let i = 0; i < masterCategories.length; i++) {
const masterCategory = masterCategories[i];
const subCategory = await subCategoryCollection.findOne({
value: masterCategory.value,
});
const productGroup = await productGroupCollection.findOne({
value: subCategory.value,
});
const products = await productCollection
.find({
subCategoryId: { $exists: false },
masterCategoryId: masterCategory._id,
})
.toArray();
for (let j = 0; j < products.length; j++) {
const product = products[j];
await productCollection.updateOne(
{ _id: product._id },
{
$set: {
subCategoryId: subCategory._id,
productGroupId: productGroup._id,
},
}
);
}
}
} finally {
await client.close();
}
};
const handler = async (req, res) => {
try {
await upload.single('file')(req, res, async (error) => {
if (error instanceof multer.MulterError) {
// Multer error occurred during file upload
res.status(400).json({ error: error.message });
} else if (error) {
// Other errors occurred
res.status(500).json({ error: 'Something went wrong', error });
} else if (!req.file) {
// No file was provided
res.status(400).json({ error: 'No file uploaded' });
} else {
const filePath = req.file.path;
const masterCategories = [];
const subCategories = [];
const productGroups = [];
const products = [];
fs.createReadStream(filePath)
.pipe(csv())
.on('data', (row) => {
const masterCategory = row.master_category.trim();
const subCategory = row.sub_category.trim();
const productGroup = row.product_group.trim();
const product = row.product.trim();
if (masterCategory !== '') {
masterCategories.push({ value: masterCategory });
}
if (subCategory !== '') {
subCategories.push({ value: subCategory });
}
if (productGroup !== '') {
productGroups.push({ value: productGroup });
}
if (product !== '') {
products.push({ value: product });
}
})
.on('end', async () => {
// Save distinct values to collections
await saveDistinctValues('master_category', masterCategories);
await saveDistinctValues('sub_category', subCategories);
await saveDistinctValues('product_group', productGroups);
await saveDistinctValues('product', products);
// Establish relationships between collections
await establishRelationships();
res
.status(200)
.json({ message: 'File uploaded and processed successfully' });
})
.on('error', (error) => {
console.error('Error processing CSV:', error.message);
res.status(500).json({ error: 'Something went wrong' });
});
}
});
} catch (error) {
console.error('Error uploading file:', error.message);
res.status(500).json({ error: 'Something went wrong' });
}
};
export default handler;
我无法理解这个错误,因为我是Next和React的新手。我已经环顾四周,我相信问题是与我使用组件的方式!
2条答案
按热度按时间0qx6xfy61#
出现此错误是因为您试图显示错误,该错误为
Object
。在这种情况下,您可以检查从后端得到的错误,并显示相关的错误消息。(如果有
setError(data.error);
)或者
出于测试目的,您可以简单地将错误显示为对象,如下所示:
mcvgt66p2#
您的React应用程序出错,因为您试图显示的
error
值是一个对象-您不能直接将对象放入JSX中。error
是一个对象可能来自这一行,在这一行中,您使用了两次键error
,第二个示例用Error
对象覆盖了第一个示例。