reactjs React未显示来自Express后端的数据

jk9hmnmh  于 2023-02-18  发布在  React
关注(0)|答案(1)|浏览(147)

我正在尝试从postgres数据库中获取数据并将其显示在表中。
server.js

require("dotenv").config();
const cors = require("cors")
const db = require("./db");
// Express Application setup
const express = require("express");
const morgan = require("morgan");
const app = express();
const bodyParser = require("body-parser");
const port = process.env.PORT;
app.listen(port, () => {
    console.log(`Server is UP and running and listening on port ${port}`);
})


app.use(cors());
app.use(bodyParser.json());

// HTTP request logger middleware
app.use(morgan("dev"));

// Get All Monsters
app.get('/monsters', async  (req, res) => {
    
    const results = await db.query(`select * from monsters`, (err, results) => {
        if (!err) {
            console.log(results)
            res.send(results.rows);
        }
    });
    db.end;
})

服务器在端口3100上,当我访问http://localhost:3100/monster时,我得到了一个很好的结果:
[{“id”:1,“image”:{“type”:“Buffer”,“data”:[105,109,103,49,46,106,112,103]},“table”:空,“cr”:“1/2”,“source”:“Monster Manual”,“type”:“Humanoid”,“size”:“Medium”,“alignment”:“N”,“tags”:空,“info”:空,“name”:“Goblin”},{“id”:13,“image”:空,“table”:空,“cr”:“1/4”,“source”:“Manual Monster”,“type”:“Monster”,“size”:“Medium“,“alignment”:“N”,“tags”:空,“info”:空,“name”:“Spiderz”}]
在Postman上也运行得很好。我看到的唯一不同之处是,当我在Postman Morgan中运行GET时,它显示了GET /monster 200 41.481 ms,而在网站上它显示了:获取/怪物304 3.514毫秒
问题似乎出在前端的某个地方(react)。

应用程序js:

import './App.css';
import MainComponent from './components/MainComponent';
import Info from './components/Info';
import Rules from './components/Rules';
import Rulebooks from './components/Rulebooks';
import Monsters from './components/Monsters';
import Adventures from './components/Adventures';
import Contact from './components/Contact';
import { Routes, Route } from 'react-router-dom';
import MonsterInfo from './components/MonsterInfo';
import { MonsterContextProvider } from './context/MonsterContext';

function App() {
  return (
    <MonsterContextProvider>
      <div>
        <Routes>
          <Route path="/" element={<MainComponent />} />
          <Route path="/info" element={<Info />} />
          <Route path="/rules" element={<Rules />} />
          <Route path="/rulebooks" element={<Rulebooks />} />
          <Route path="/monsters" element={<Monsters />} />
          {/* <Route path="/monsters/:id" element={<MonsterInfo />} /> */}
          <Route path="/adventures" element={<Adventures />} />
          <Route path="/contact" element={<Contact />} />
        </Routes>
      </div>
    </MonsterContextProvider>
   
  )
  };

export default App;

**上下文:**MonsterContext.js

import React, { useState, createContext } from "react";

export const MonsterContext = createContext();

export const MonsterContextProvider = props => {
    const [monsters, setMonsters] = useState([])

    // const addMonsters = (monsters) => {
    //     setMonsters([...monsters, monsters]);
    // }
    return (
        <MonsterContext.Provider value={{ monsters: monsters, setMonsters }}>
            {props.children}
        </MonsterContext.Provider>
    )
}

**API:**怪物探索者网站

import axios from "axios";

export default axios.create({
    baseURL: "http://192.168.0.118:3100/"
});

**显示数据的页面:**MonsterList.jsx

import "./Monsters.css";
import React, { useEffect, useContext } from 'react';
import MonsterFinder from "../apis/MonsterFinder";
import { useNavigate, Link } from "react-router-dom";
import { MonsterContext } from '../context/MonsterContext';

const MonsterList = (props) => {
    const { monsters, setMonsters } = useContext(MonsterContext);
    const navigate = useNavigate()

    useEffect(() => {
        const fetchData = async () => {
        try {
          const response = await MonsterFinder.get("/monsters");
           setMonsters(response.data.data.monsters);
          
        } catch (err) {}
    };
       fetchData();     
    }, []);

    return (
             
        <div className="app-container">
            <h1>Monsters</h1>
            <table>
                <thead>
                    <tr>
                        <th> </th>
                        <th>Cr</th>
                        <th>Name</th>
                        <th>Source</th>
                        <th>Type</th>
                        <th>Size</th>
                        <th>Alignment</th>
                        <th>Tag</th>
                        <th>Info</th>
                    </tr>
                </thead>
                <tbody>
                    {monsters.map((monster) => {
                        return (
                        <tr>
                            <td><img src={require(`../media/${monster.Image}`)} alt={monster.Name} height="25" width="25" /></td>
                            <td>{monster.Cr}</td>
                            <td>{monster.Name}</td>
                            <td>{monster.Source}</td>
                            <td>{monster.Type}</td>
                            <td>{monster.Size}</td>
                            <td>{monster.Alignment}</td>
                            <td>{monster.Tag}</td>
                            <td><button className="button"><Link className="links" to={`/monsterinfo/${monster.Name}`}>Info</Link></button></td>
                        </tr>
                        );
                    })}
                    
                </tbody>
            </table>
        </div>
        
    )
};

export default MonsterList

在server.js I console.log(results)中,控制台显示:

GET /monsters 304 37.024 ms - -
Result {
  command: 'SELECT',
  rowCount: 2,
  oid: null,
  rows: [
    {
      id: 1,
      image: <Buffer 69 6d 67 31 2e 6a 70 67>,
      table: null,
      cr: '1/2',
      source: 'Monster Manual',
      type: 'Humanoid',
      size: 'Medium',
      alignment: 'N',
      tags: null,
      info: null,
      name: 'Goblin'
    },
    {
      id: 13,
      image: null,
      table: null,
      cr: '1/4',
      source: 'Monster Manual',
      type: 'Monster',
      size: 'Medium',
      alignment: 'N',
      tags: null,
      info: null,
      name: 'Spiderz'
    }
  ],
  fields: [
    Field {
      name: 'id',
      tableID: 16391,
      columnID: 1,
      dataTypeID: 23,
      dataTypeSize: 4,
      dataTypeModifier: -1,
      format: 'text'
    },
    
    etc

因此,数据收集,但当我检查网页时,我只看到标题,并得到:

您会看到MonsterList数组=(0)

问题不在于我如何显示tbody数据,当我使用mock_data. json文件时,它工作正常。

uyto3xhc

uyto3xhc1#

首先,我想让你注意一下你的“useEffect”钩子,如果你在development phase中,react会挂载和卸载你的组件,让你的组件渲染两次,这个行为是为了更好地捕捉开发阶段的bug。learn more
我认为你得到http 304是因为你的组件获取了两次数据,你的端点发送304是因为他看到了相同的负载被请求。
您可以使用useRef来解决这个问题,如下所示:

// We set a ref to persist a variable between renders
const alreadyRunned = useRef(false)

useEffect(() => {
  if(alreadyRunned.current == false) {
  // We set the "current" property to true, to execute only once the useEffect
  alreadyRunned.current = true;
  
    // Your code here
  }
 });
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

相关问题