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

React前端bookdata变量在服务端交互后变为null的问题求助

问题描述

与服务端完成交互后,bookdata变量变为null,页面无法显示任何信息。所有查询请求均能正常返回数据,推测问题出在前端。尝试过多种方法限制bookdata仅更新一次,但均未成功,耗时数小时仍未解决,恳请帮忙排查。


前端代码

import { useEffect, useState } from 'react'
import { useLocation } from 'react-router-dom';
import axios from 'axios';

export default function Book() {

  interface Book {
    id_ksiazki: number;
    tytul: string;
    autor: string;
    cena: Float32Array;
    wydawnictwo: string;
    data_premiery: string;
    liczba_stron: number;
  }

  const [bookdata,setBookdata] = useState<Book>();

  const location = useLocation();
  const searchParams = new URLSearchParams(location.search);
  const id = searchParams.get('id');


  const sendDataToBackend = async () => {
    axios.get('http://localhost:3000/book', {
      params: {
        id: id,
      }
    })
    .then(response => {
      const data = response.data; // 从后端获取的数据
    })
    .catch(error => {
      console.error('GET请求错误:', error);
    });
  };

  useEffect(() => {
    if (id) {
      sendDataToBackend();
    }
  
    axios.get('http://localhost:3000/book', {
      params: {
        id: id,
      }
    })
    .then(response => {
      const data = response.data; // 获取到的数据
      if(!bookdata)
      {
      setBookdata(data);
      console.log(data);
      }
    })
    .catch(error => {
      console.error('GET请求错误:', error);
    });
  
  }, [id]);

  return (
    <div id="book-page">
      <h1>书籍页面</h1>
      <h2>{bookdata?.tytul}</h2>
      <h3>{bookdata?.autor}</h3>
      <h4>{bookdata?.wydawnictwo}</h4>
    </div>
  );
}

后端代码

import express from 'express'
import cors from 'cors'
import mysql from 'mysql2'
//import bodyParser from 'body-parser'
//import bcrypt from 'bcrypt'
//import jwt from 'jsonwebtoken'
//import dotenv from 'dotenv'

const corsOptions = {
    origin: 'http://localhost:5173', 
};

const app = express();
app.use(cors(corsOptions));

app.use(express.json());

const pool = mysql.createPool({
    host: 'localhost',
    user: 'root',
    password: '',
    database: 'shelfparrot'
}).promise()


app.get('/sprzedane', async (req, res) => {
    try {
        const [row] = await pool.query("SELECT COUNT(*) AS sprzedane FROM zamowienia");
        const wynik = row[0]; 
        res.json(wynik); // 返回结果为JSON
    } catch (error) {
        console.error(error);
        res.status(500).json({ message: "服务器错误" });
    }
});

app.get('/ksiazki', async (req,res) => {
    try {
        const [row] = await pool.query("SELECT * FROM ksiazki");
        res.json(row)
    } catch (error) {
        console.log(error);
        res.status(500).json({ message: "服务器错误" });
    }
})


app.get('/book', async (req, res) => {
    try {
        const id = req.query.id;
        const zap = "SELECT * FROM ksiazki WHERE id_ksiazki = ?";
        const [row] = await pool.query(zap, id + 1);
        console.log(row);
        res.json(row);
    } catch (error) {
        console.log(error);
        res.status(500).json({ message: "服务器错误" });
    }
});
 
app.listen(3000, () => {
    console.log('服务器运行在3000端口');
});

控制台输出(打印了两次)

[{…}]
0: 
autor: "Karol Dickens"
cena: 50
data-premiery: "2022-05-31"
id_ksiazki: 1
liczba-stron: 600
tytul: "Opowieść o dwóch miastach"
wydawnictwo: "Wydawnictwo Zysk i S-ka"
[[Prototype]]: Object
length: 1
[[Prototype]]: Array(0)

问题排查与修复方案

核心问题点

  1. 数据格式不匹配:后端返回的是包含单个对象的数组,但前端Book接口定义的是单个对象类型,直接将数组赋值给bookdata会导致后续无法正确读取属性。
  2. 重复请求+错误的状态判断:useEffect中同时发起两次相同请求,且if(!bookdata)的判断依赖闭包捕获的初始值(始终为undefined),会导致重复赋值;若某次请求返回空数组,bookdata会被设为数组,自然无法读取对象属性。
  3. 字段名与类型不匹配:
    • 后端返回字段为data-premiery、liczba-stron,但前端接口定义为data_premiery、liczba_stron,下划线与短横线不匹配导致字段映射失败;
    • 前端将cena定义为Float32Array,但后端返回的是普通数字,类型不兼容。
  4. 后端参数错误:id + 1会将字符串类型的id拼接为id1(如id为"1"时变成"11"),导致查询错误。

修复步骤

1. 修正后端数据返回与参数问题

// 后端/book接口修改
app.get('/book', async (req, res) => {
    try {
        const id = req.query.id;
        const zap = "SELECT * FROM ksiazki WHERE id_ksiazki = ?";
        // 参数传入数组避免字符串拼接问题,移除错误的id+1
        const [row] = await pool.query(zap, [id]); 
        console.log(row);
        // 返回单个对象而非数组,若查询不到则返回null
        res.json(row[0] || null);
    } catch (error) {
        console.log(error);
        res.status(500).json({ message: "服务器错误" });
    }
});

2. 修正前端接口定义

interface Book {
  id_ksiazki: number;
  tytul: string;
  autor: string;
  cena: number; // 改为与后端匹配的number类型
  wydawnictwo: string;
  "data-premiery": string; // 与后端字段名保持一致,或让后端用AS重命名为下划线格式
  "liczba-stron": number;
}

3. 清理useEffect中的重复请求,优化状态更新

useEffect(() => {
  if (!id) return;

  // 移除重复请求,只保留一个
  axios.get('http://localhost:3000/book', {
    params: { id }
  })
  .then(response => {
    const book = response.data;
    setBookdata(book);
  })
  .catch(error => {
    console.error('请求失败:', error);
  });
}, [id]);

4. 可选:添加加载状态优化体验

const [loading, setLoading] = useState(true);

useEffect(() => {
  if (!id) return;
  setLoading(true);
  axios.get('http://localhost:3000/book', { params: { id } })
  .then(response => {
    const book = response.data;
    setBookdata(book);
  })
  .catch(error => {
    console.error('请求失败:', error);
  })
  .finally(() => {
    setLoading(false);
  });
}, [id]);

// 渲染逻辑调整
return (
  <div id="book-page">
    <h1>书籍页面</h1>
    {loading ? (
      <p>加载中...</p>
    ) : bookdata ? (
      <>
        <h2>{bookdata.tytul}</h2>
        <h3>{bookdata.autor}</h3>
        <h4>{bookdata.wydawnictwo}</h4>
      </>
    ) : (
      <p>未找到该书籍</p>
    )}
  </div>
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:35:53