Next.js/React:如何避免特定状态变更时触发useEffect?
销售数据图表页面的状态更新问题及解决
项目背景
我开发了一个展示销售数据的图表页面,核心功能包括:
- 用户更改维度、筛选值和周期时,通过REST API更新图表数据
- 支持保存和加载自定义图表设置
初始实现代码如下:
数据更新的Effect逻辑
useEffect(async () => { let [startDate, endDate] = getReportPeriod({target: { innerText: period}}) // 获取格式化日期字符串 getReportData(startDate, endDate) // 调用REST API获取图表数据的函数 }, [filteredDimensions, dimensions, dimensionTime])
加载自定义报告设置的逻辑
const loadCustomReport = async(reportName) => { let res = await axios.post('/api/customReport/loadReport', { report_name: reportName }) // 获取报告设置 let setting = JSON.parse(res.data[0].report_setting) // 将报告设置解析为JSON setRevenue(setting.metrics.revenue) setImpression(setting.metrics.impression) setClicks(setting.metrics.clicks) setCPM(setting.metrics.CPM) setCTR(setting.metrics.CTR) setDimensions(setting.dimensions) setFilteredDimensions(setting.filteredDimensions) }
遇到的问题
加载自定义报告时,setDimensions和setFilteredDimensions会分别触发一次useEffect,但由于接口响应时间不一致,有时获取到的图表数据并未应用完整的设置。我想知道是否有办法在调用setDimensions时跳过useEffect的执行?我已经考虑过将维度设置和筛选设置合并为单个状态,但好奇是否有其他解决方案。
解决方案与代码修改
社区中@Gabriele Petrioli给出的解决方案正好符合我的需求,@man.in.the.jukebox和@Brandon Pelton-Cox的建议也很有参考价值。在看到@Gabriele Petrioli的回答前,我已经自行完成了代码修改,修改后的代码如下:
更新后的Effect逻辑
useEffect(async () => { let [startDate, endDate] = getReportPeriod({target: { innerText: period}}) getReportData(startDate, endDate) }, [filteredDimensions, dimensionTime])
维度操作的处理函数
// 向当前dimensions状态添加维度的按钮处理函数 const addDimension = (dimension) => { setDimensions([ ...dimensions, dimension ]) let [startDate, endDate] = getReportPeriod({target: { innerText: period}}) getReportData(startDate, endDate) } // 从当前dimensions状态移除维度的按钮处理函数 const removeDimension = (idx) => { let tempDimensions = [...dimensions] tempDimensions.splice(idx, 1) setDimensions(tempDimensions) let [startDate, endDate] = getReportPeriod({target: { innerText: period}}) getReportData(startDate, endDate) }
加载自定义报告设置的逻辑(未改动)
const loadCustomReport = async(reportName) => { let res = await axios.post('/api/customReport/loadReport', { report_name: reportName }) let setting = JSON.parse(res.data[0].report_setting) setRevenue(setting.metrics.revenue) setImpression(setting.metrics.impression) setClicks(setting.metrics.clicks) setCPM(setting.metrics.CPM) setCTR(setting.metrics.CTR) setDimensions(setting.dimensions) setFilteredDimensions(setting.filteredDimensions) }
感谢各位提供的宝贵建议。
内容的提问来源于stack exchange,提问作者Young-Kwang Oh
相关产品推荐
相关产品推荐

