javascript - 我的 REACT 应用程序出现路由问题
问题描述
好的,这是我的问题。我有这个 REACT 应用程序,到目前为止,当我在我的计算机上的本地主机上运行它时,我所拥有的一切运行良好。我将它部署在 Heroku,应用程序加载但反应与我的本地主机上的反应非常不同。这是发生了什么。
在我的本地主机上,当应用程序加载主页时,在导航栏上,有几个选项可供选择,包括门票。如果您单击门票选项,它会加载门票页面。从那里,在页面的左侧,您可以选择输入新票证并将其保存到 Mongo 数据库。在页面的右侧,它列出了所有当前已输入并存储在 Mongo 数据库中的票证。您可以单击其中一张工单以查看工单详细信息,或者您还可以选择从数据库中删除工单。就像我说的,在本地运行一切正常。
问题是,当我从 Heroku 加载部署的版本时,它会加载主页,但是当我单击导航栏中的票证选项时,它没有加载票证页面,它只返回 JSON 格式的所有取消票证. 它实际上为导航栏上的所有选项(客户、材料和票证)执行此操作。我一直在弄乱我的路线试图找到问题并且没有成功。我有点猜测/希望这是我缺少的一些简单的东西,但我的部分问题是,我有很多代码,我不确定我需要在这里发布什么。所以我要发布我的 Server.js 和一些路线,我想从那里开始。
服务器.js
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const routes = require("./routes");
const app = express();
const port = process.env.PORT || 3030;
const customers = require('./routes/api/Customers');
const materials = require('./routes/api/Materials');
const tickets = require('./routes/api/Tickets');
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
}
const DB = process.env.DB;
// app.use('/', customers);/
app.use('/customers', customers);
app.use('/materials', materials)
app.use('/tickets', tickets)
mongoose
.connect(DB,{ useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false})
.then(() => console.log('MongoDB Connected!'))
.catch(err => console.log(err));
app.listen(port, () => console.log(`Server started on port ${port}`));
路线>api>index.js
const path = require("path");
const router = require("express").Router();
const apiRoutes = require("./api");
// API Routes
router.use("/api", apiRoutes);
// If no API routes are hit, send the React app
router.use(function(req, res) {
res.sendFile(path.join(__dirname, "../client/build/index.html"));
});
module.exports = router;
路线>api>Tickets.js
onst express = require('express');
const router = express.Router();
const ticketController = require('../../controllers/ticket');
router.route('/')
.get(ticketController.index)
.post(ticketController.newTicket);
router.route('/:ticketID')
.get(ticketController.getTicket)
.put(ticketController.replaceTicket)
.patch(ticketController.updateTicket)
.delete(ticketController.removeTicket);
module.exports = router;
这是来自 React 应用程序的代码:
API.js
import axios from "axios";
export default {
// Gets all tickets
getTickets: function() {
return axios.get("/Tickets");
},
// Gets the ticket with the given id
getTicket: function(id) {
return axios.get("/Tickets/" + id);
},
// Deletes the ticket with the given id
deleteTicket: function(id) {
return axios.delete("/Tickets/" + id);
},
// Saves a ticket to the database
saveTicket: function(ticketData) {
return axios.post("/Tickets", ticketData);
},
// Gets all Customers
getCustomers: function() {
return axios.get("/Customers");
},
// Gets the customer with the given id
getCustomer: function(id) {
return axios.get("/Customers/" + id);
},
getCustLocations: function(id) {
return axios.get("/Customers/" + id + "/locations");
},
// Deletes the customer with the given id
deleteCustomer: function(id) {
return axios.delete("/Customers/" + id);
},
// Saves a customer to the database
saveCustomer: function(customerData) {
return axios.post("/Customers", customerData);
},
// Gets all Materials
getMaterials: function() {
return axios.get("/Materials");
},
// Gets the Material with the given id
getMaterial: function(id) {
return axios.get("/Materials/" + id);
},
// Deletes the Material with the given id
deleteMaterial: function(id) {
return axios.delete("/materials/" + id);
},
// Saves a Material to the database
saveMaterial: function(materialData) {
return axios.post("/materials", materialData);
},
};
门票.js
import React, { useState, useEffect } from "react";
import DeleteBtn from "../DeleteBtn";
import Jumbotron from "../Jumbotron";
import API from "../../utils/API";
import { Link } from "react-router-dom";
import { Col, Row, Container } from "../Grid";
import { List, ListItem } from "../List";
import { Input, FormBtn } from "../Form";
const moment = require('moment');
function Tickets(props) {
// Setting our component's initial state
const [tickets, setTickets] = useState([])
const [formObject, setFormObject] = useState({})
const [customers, setCustomers] = useState([])
const [materials, setMaterials] = useState([])
console.log("Customer = ", customers)
// Load all tickets and store them with setTickets
useEffect(() => {
loadTickets()
}, [])
// Loads all tickets and sets them to tickets
function loadTickets() {
API.getTickets()
.then(res =>
setTickets(res.data)
)
.catch(err => console.log(err));
};
// Load all Customers and store them with setCustomer
useEffect(() => {
loadCustomers()
}, [])
// Loads all customers and sets them to customers
function loadCustomers() {
API.getCustomers()
.then(res =>
setCustomers(res.data)
)
.catch(err => console.log(err));
};
// Load all materials and store them with setMaterials
useEffect(() => {
loadMaterials()
}, [])
// Loads all materials and sets them to customers
function loadMaterials() {
API.getMaterials()
.then(res =>
setMaterials(res.data)
)
.catch(err => console.log(err));
};
// Deletes a ticket from the database with a given id, then reloads tickets from the db
function deleteTicket(id) {
API.deleteTicket(id)
.then(res => loadTickets())
.catch(err => console.log(err));
}
// Handles updating component state when the user types into the input field
function handleInputChange(event) {
const { name, value } = event.target;
setFormObject({...formObject, [name]: value})
};
// When the form is submitted, use the API.saveTicket method to save the ticket data
// Then reload tickets from the database
function handleFormSubmit(event) {
event.preventDefault();
if (formObject.ticketDate) {
API.saveTicket({
ticketDate: formObject.ticketDate,
ticketNum: formObject.ticketNum,
ticketCust: formObject.ticketCust,
ticketMaterial: formObject.ticketMaterial,
ticketTareWeight: formObject.ticketTareWeight,
ticketGrossWeight: formObject.ticketGrossWeight,
ticketNetWeight: formObject.ticketGrossWeight - formObject.ticketTareWeight
})
.then(res => loadTickets())
.catch(err => console.log(err));
document.getElementById("ticketFrm").reset();
setFormObject({})
}
};
return (
<Container fluid>
<Row>
<Col size="md-6">
<Jumbotron>
<h1>Add Ticket</h1>
</Jumbotron>
<form id="ticketFrm">
<Input
onChange={handleInputChange}
name="ticketDate"
placeholder="Date"
/>
<Input
onChange={handleInputChange}
name="ticketNum"
placeholder="Ticket Number (required)"
/>
<select onChange={handleInputChange}
name="ticketCust"
style={{width: '100%', height: 35, marginBottom: 15}}>
{customers.map((customers, ii ) => (
<>
<option key={ii} value="" hidden>Select Customer</option>
<option key={customers.custName}>{customers.custName}</option>
</>
))}
</select>
<select onChange={handleInputChange}
name="ticketMaterial"
style={{width: '100%', height: 35, marginBottom: 15}}>
{materials.map((materials, ii ) => (
<>
<option key={ii} value="" hidden>Select Material</option>
<option key={materials._id}>{materials.name}</option>
</>
))}
</select>
<Input
onChange={handleInputChange}
name="ticketTareWeight"
placeholder="Tare Weight"
/>
<Input
onChange={handleInputChange}
name="ticketGrossWeight"
placeholder="Gross Weight"
/>
<FormBtn
disabled={!(formObject.ticketNum)}
onClick={handleFormSubmit}>
Submit Ticket
</FormBtn>
</form>
</Col>
<Col size="md-6 sm-12">
<Jumbotron>
<h1>Current Tickets</h1>
</Jumbotron>
{tickets.length ? (
<List>
{tickets.map(tickets => (
<ListItem key={tickets._id}>
<Link to={"/Tickets/" + tickets._id}>
<strong>
Ticket Date - {moment(tickets.ticketDate).format("MM-DD-YYYY")}
<br></br>
Ticket# - {tickets.ticketNum}
<br></br>
{tickets.ticketCust}
</strong>
</Link>
<DeleteBtn onClick={() => deleteTicket(tickets._id)}/>
</ListItem>
))}
</List>
) : (
<h3>No Results to Display</h3>
)}
</Col>
</Row>
</Container>
);
}
export default Tickets;
APP.js
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import NavBar from './components/NavBar';
import Tickets from './components/pages/Tickets';
import TicketDetails from './components/pages/TicketDetails';
import Customers from './components/pages/Customers';
import CustomerDetails from './components/pages/CustomerDetails';
import Materials from './components/pages/Materials';
import MatDetails from './components/pages/MatDetails';
import 'bootstrap/dist/css/bootstrap.min.css';
import '../src/components/App.css';
function App() {
return (
<Router>
<div>
<NavBar/>
<Switch>
<Route exact path={"/tickets"}>
<Tickets />
</Route>
<Route exact path={"/tickets/:id"}>
<TicketDetails />
</Route>
<Route exact path={"/customers"}>
<Customers />
</Route>
<Route exact path={"/customers/:id"}>
<CustomerDetails />
</Route>
<Route exact path={"/materials"}>
<Materials />
</Route>
<Route exact path={"/materials/:id"}>
<MatDetails />
</Route>
</Switch>
</div>
</Router>
);
}
export default App;
导航栏.js
import React, { useState } from 'react';
import {
Collapse,
Navbar,
NavbarToggler,
NavbarBrand,
Nav,
NavItem,
NavLink,
NavbarText
} from 'reactstrap';
const NavBar = (props) => {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => setIsOpen(!isOpen);
return (
<div>
<Navbar color="dark" dark expand="md">
<NavbarBrand href="/">HAMMER</NavbarBrand>
<NavbarToggler onClick={toggle} />
<Collapse isOpen={isOpen} navbar>
<Nav className="mr-auto" navbar>
<NavItem>
<NavLink href="/Tickets">Tickets</NavLink>
</NavItem>
<NavItem>
<NavLink href="/Customers">Customers</NavLink>
</NavItem>
<NavItem>
<NavLink href="/Materials">Materials</NavLink>
</NavItem>
</Nav>
<NavbarText >Nathan Huber</NavbarText>
</Collapse>
</Navbar>
</div>
);
}
export default NavBar;
我很感激任何帮助!
谢谢,
弥敦道
解决方案
原来,我的构建文件夹有问题。我还编辑了我的 server.js 文件。我变了:
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
}
至:
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
app.get("/*", function(req, res) {
res.sendFile(path.join(__dirname, "./client/build/index.html"));
});
}
else {
app.use(express.static(path.join(__dirname, '/client/public')));
app.get("/*", function(req, res) {
res.sendFile(path.join(__dirname, "./client/public/index.html"));
});
}
这似乎纠正了我的路线问题,但似乎也打开了一个全新的蠕虫罐头,哈哈。现在,当我单击导航栏中的门票链接时,它似乎打开了门票页面,但随后它消失并引发了一堆错误。我假设路由器正在工作,因为它至少开始打开页面。如果需要,我将处理这些新错误并提交一个新问题。
谢谢您的帮助。
-N8
推荐阅读
- react-native - 方法 [RNCPushNotificationIOS addNotificationRequest] 中的未知参数类型“UNNotificationRequest”
- reactjs - Uncaught SyntaxError: Unexpected token '<' ReactJS 应用程序部署在 AKS Pod 的 NGINX 中
- javascript - Jquery 或 Javascript 在数组对象中查找索引
- algorithm - 带约束的连接算法
- c++ - 我应该如何打印 Char 的指针
- blockchain - 交易在具有相同参数的监控交易之前被挖掘
- java - 无限滚动视图 firebase 实时数据库错误
- java - 使用 _barVisualizer.setAudioSessionId(audioSessionId); 时应用程序崩溃;
- django - RuntimeError:模型类 himalayadashbords.clients.models.Client 未声明显式 app_label 且不在 INSTALLED_APPS 中的应用程序中
- java - AlertDialog 不断崩溃