You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Hooks对接Express MongoDB服务GET请求返回空数组问题求助

问题根因

页面刷新时初始状态todos为[],依赖todos的useEffect会先于获取服务端数据的useEffect执行,直接把空数组同步到后端覆盖了原有待办数据,导致后续get请求拿到的永远是空数组。同时后端接口存在未返回响应、中间件逻辑缺失的问题,会导致请求异常。


修复方案

前端修改(Todo.jsx)

新增加载状态标记,避免未拿到服务端数据时就把空数组同步到后端:

// 新增加载状态
const [isDataLoaded, setIsDataLoaded] = useState(false)

const postTodo = (todos) => {
  // 仅数据加载完成后才执行同步
  if (!isDataLoaded) return
  console.log(todos);
  axios.post("http://localhost:4000/api/todos", todos, {
    headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${token}`,
    }
  })
    .then(res => {
      console.log(res);
    })
    .catch(err => {
      console.log(err);
    })
}
useEffect(() => {
  postTodo(todos) 
  // eslint-disable-next-line react-hooks/exhaustive-deps
}, [todos, isDataLoaded])

useEffect(() => {
  axios.get("http://localhost:4000/api/todos", {
    headers: {
      "Content-Type": "application/json",
      "Authorization": `Bearer ${token}`,
    }
  })
    .then(res => {
      console.log(res);
      setTodos(res.data.todos)
      // 标记数据加载完成,允许后续同步操作
      setIsDataLoaded(true)
    })
    .catch(err => {
      console.log(err);
    })
}, [])

后端修改(server.js)

补全中间件响应逻辑、接口返回逻辑,增加异常捕获:

const authCheck = (req, res, next) => {
  if (req.headers['authorization']) {
    const token = req.headers['authorization'].split(" ")
    if (token[0] !== 'Bearer') {
      return res.send({ status: 'error', error: 'invalid request' });
    } else {
      try {
        req.jwt = jwt.verify(token[1], process.env.jwtSECRET);
        return next();
      } catch (err) {
        return res.send({ status: 'error', error: 'invalid token' });
      }
    }
  }
  // 补全缺失Authorization头的响应逻辑
  return res.send({ status: 'error', error: 'missing authorization header' });
}

app.post("/api/todos", authCheck, async (req, res) => {
  try {
    const todos = req.body
    console.log(todos);
    const { id } = req.jwt
    // 传入{new: true}可返回更新后的用户数据,按需选择
    const user = await User.findByIdAndUpdate(id, { "todos": todos }, { new: true })
    // 必须返回响应,否则前端请求会超时
    return res.send({ status: "ok", todos: user.todos })
  } catch (err) {
    console.log(err)
    return res.send({ status: "error", error: "update todo failed" })
  }
})
app.get("/api/todos", authCheck, async (req, res) => {
  try {
    const { id } = req.jwt
    const user = await User.findById(id)
    console.log(user) // 修正原代码的日志拼写错误
    res.send({
      status: "ok", todos: user.todos })
  } catch (err) {
    console.log(err)
    res.send({ status: "error", error: "fetch todo failed" })
  }
})

内容的提问来源于stack exchange,提问作者Kaartik Nayak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 01:18:03