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
相关产品推荐
相关产品推荐

