React应用热加载仅单独启前后端生效,使用concurrently时数据丢失代理报错
问题根因与解决步骤
1. 修复nodemon监听范围,避免前端修改触发后端重启
当前nodemon默认监听项目根目录下所有.js文件改动,修改前端Paintings.js时会触发后端服务自动重启:
- 后端重启过程中端口暂时不可用,会抛出
Proxy error代理错误 - 后端每次重启都会执行
addDataToCollection()方法,先调用Product.deleteMany()清空所有画作数据再重新插入,间隙内前端请求会拿到空数据,导致UI渲染为空
解决方法:
在package.json中修改dev脚本,给nodemon指定仅监听后端文件夹改动:
"dev": "concurrently \"nodemon --watch backend backend/server\" \"npm run client\""
也可以在后端根目录新建nodemon.json实现相同效果:
{ "watch": ["backend/"] }
2. 修改后端初始数据导入逻辑,避免每次启动都清空重插数据
当前逻辑每次后端启动都会清空所有数据再重插,就算后端正常重启也会丢数据,建议加启动参数控制,仅手动指定时才导入数据:
修改server.js中addDataToCollection的调用逻辑:
// 只有启动时加了--import-data参数才执行数据导入 if (process.argv.includes('--import-data')) { addDataToCollection() }
后续需要初始化数据时,手动执行node backend/server --import-data即可,正常启动服务不会再删数据。
3. 修复Paintings.js组件的不合理逻辑
当前useEffect加了多余的清理函数,组件卸载时还会调用fetchData,不仅无用还可能引发内存泄漏警告,loader状态处理逻辑也存在问题,修改后代码如下:
import React, { useState, useEffect, useCallback } from 'react' import './styles.css' import axios from 'axios' const Products = () => { const [paintings, setPaintings] = useState([]) const [loader, setLoader] = useState(true) const fetchData = useCallback(async () => { setLoader(true) try { const res = await axios.get('/paintings') setPaintings(res.data) setLoader(false) } catch (error) { console.log(error) setLoader(false) // 报错也关闭loader,避免一直展示加载动画 } }, []) useEffect(() => { fetchData() // 移除多余的清理函数 }, [fetchData]) // 将loader判断提到map外层,避免数据为空时加载动画不展示 if (loader) { return ( <div className="paintingsContainer"> <div className="loaderPng"> <img src={process.env.PUBLIC_URL + '/img/loader.gif'} alt="spinner" className="spinner" style={{ width: "100px" }} /> </div> </div> ) } return ( <div className="paintingsContainer"> {paintings.map(painting => { const { name, price, _id, imgSrc, artNr } = painting return ( <div className="products" key={_id}> <div className="productName">{name}</div> <div className="price">Price: ${price}</div> <div className="imageBox"> <img src={process.env.PUBLIC_URL + `${imgSrc}`} alt="item" className="image" /> </div> <div className="footers cart">Add to cart</div> <div className="footers buy">Buy this product</div> <div className="footers art">art-nr:{artNr}</div> </div> ) })} </div> ) } export default Products
4. 修复代理错误问题
如果还有代理报错,检查前端package.json里的proxy配置,确保配置为"proxy": "http://localhost:5000",不要添加多余后缀,修改后重启前端服务生效。
内容的提问来源于stack exchange,提问作者Noud
相关产品推荐
相关产品推荐

