Express后端axios调用Unbounce数据不更新,前端仅获初始值如何解决
解决方案
问题根因
你遇到的问题是前后端两处错误共同导致的:
后端错误
- 路由重复注册:你把
/api/hello的路由定义写在了定时执行的countCount函数内,Express中先注册的路由会优先匹配生效,后续重复注册的同路径路由永远不会执行,接口永远返回首次注册时闭包捕获的初始值。 - 局部变量无法同步:
isCount是countCount的内部局部变量,首次注册的路由闭包只会引用第一次执行时的isCount值,后续定时任务生成的新isCount和路由引用的不是同一个变量,接口返回值自然不会更新。 - 冗余定时任务:你定义了两个每分钟执行的cron任务都调用
getCount,属于完全无用的冗余逻辑。
前端错误
- 接口仅调用一次:你当前的
useEffect依赖项是稳定的setResult函数,只会在组件挂载时调用一次接口拉取数据,后续不会主动刷新,就算后端返回值更新了前端也拿不到。
修正后代码
后端代码
const express = require('express'); const axios = require("axios"); const cors = require("cors"); const cron = require("node-cron"); const PORT = process.env.PORT || 5000; const server = express(); server.use(express.json()); server.use(express.urlencoded({ extended: true })); server.use(cors()); // 全局变量存储最新的统计值 let latestCount = 0; const getCount = async () => { const config = { auth: { username: 'APIKEY', }, headers: { 'accept': 'application/vnd.unbounce.api.v0.4+json' } }; try { const res = await axios.get('https://api.unbounce.com/pages/PAGE_ID', config) return res.data.tests.current.conversions; } catch (error) { console.error(error?.response?.data || error.message) // 报错时返回旧值,避免前端拿空 return latestCount } } // 只保留一个定时任务,每分钟更新全局变量 cron.schedule('* * * * *', async function() { console.log('更新统计值'); latestCount = await getCount(); console.log('最新值:', latestCount) }); // 路由只定义一次,每次请求返回当前最新的全局变量 server.get("/api/hello", async function (req, res) { res.json(latestCount); }); server.listen(PORT, () => console.log(`listening on port ${PORT}`));
前端代码
import "./App.css"; import { useState, useEffect } from 'react'; import axios from "./axios"; import { ProgressBar } from 'react-bootstrap'; import 'bootstrap/dist/css/bootstrap.min.css'; function App() { const [result, setResult] = useState(0); function getInfo() { axios.get("api/hello").then((response) => { console.log("拉取到最新值", response.data) setResult(response.data); }); } useEffect(() => { // 组件挂载时先拉取一次 getInfo() // 启动定时器,每分钟拉取一次 const timer = setInterval(() => { getInfo() }, 60 * 1000) // 组件卸载时清除定时器,避免内存泄漏 return () => clearInterval(timer) }, []); const total = result/1000000; const percent = total * 100; return ( <main> <ProgressBar now={percent} label={`${Math.round(percent)}%`} /> <div className="test">Some text that shows the result at the end {result}</div> </main> ); } export default App;
内容的提问来源于stack exchange,提问作者Andrew Haberman
相关产品推荐
相关产品推荐

