尝试使用空输入字段提交时 React 应用程序崩溃
React app crashed when trying to submit with empty input field
请帮我解决这个问题,因为我搜索了所有 Internet 但找不到答案:(
我正在使用 MERN Stack 制作一个网站,我遇到了一个问题:
Whenever I click Update on the empty input field, my app would crash.
When I catch the error in the Axios update request, it just says Network Error.
请问有没有办法解决这个错误?
也许如果输入字段为空,更新按钮不会触发?
这是我的代码:
// DinnerIdeas.js
import React, { useState, useEffect } from "react"
import './DinnerIdeas.css'
import Axios from "axios"
import FoodListComponent from "../FoodListComponent";
import FormComponent from "../FormComponent";
function DinnerIdeas() {
const [foodName, setFoodName] = useState('')
const [isVegetarian, setVegetarian] = useState(false)
const [priceRange, setPriceRange] = useState('$')
const [newFoodName, setNewFoodName] = useState(null)
const [foodList, setFoodList] = useState([])
// Read:
useEffect(() => {
let unmounted = false
Axios.get("http://localhost:3001/read")
.then((response) => {
if (!unmounted) {
setFoodList(response.data)
}
})
.catch(error => {
console.log(`Hey, the error is ${error}`)
return
})
return () => {
unmounted = true
}
}, [foodList])
// Create:
const addToList = () => {
Axios.post(
"http://localhost:3001/insert",
{
foodName: foodName,
isVegetarian: isVegetarian,
priceRange: priceRange,
}
)
}
// Update:
const updateFood = (id) => {
Axios.put("http://localhost:3001/update", {
id: id,
newFoodName: newFoodName,
})
.catch(error => console.log(`Hey, the error is ${error}`))
}
// Delete:
const deleteFood = (id) => {
Axios.delete(`http://localhost:3001/delete/${id}`)
}
return (
<section className="dinner-ideas">
<FormComponent
setFoodName={setFoodName}
setVegetarian={setVegetarian}
setPriceRange={setPriceRange}
addToList={addToList}
/>
<FoodListComponent
foodList={foodList}
setNewFoodName={setNewFoodName}
updateFood={updateFood}
deleteFood={deleteFood}
/>
</section>
);
}
export default DinnerIdeas;
表单组件:
export default function FormComponent(props) {
return (
<div className="dinner container">
<h1 className="dinner--title">Dinner Ideas</h1>
<form>
<div className="form-group">
<label htmlFor="name">Food name:</label>
<input
type="text"
name="name"
placeholder="Ex: Pesto Pasta"
maxLength="50"
onChange={(event) => {props.setFoodName(event.target.value)}}
required
/>
</div>
<br />
<div className="form-group">
<label htmlFor="vegetarian"> Is this dish Vegetarian?</label>
<select
name="vegetarian"
onChange={(event) => {props.setVegetarian(event.target.value)}}
>
<option value="false">No</option>
<option value="true">Yes</option>
</select>
</div>
<br />
<div className="form-group">
<label htmlFor="price">Price range:</label>
<select
name="price"
onChange={(event) => {props.setPriceRange(event.target.value)}}
>
<option value="$">$</option>
<option value="$$">$$</option>
<option value="$$$">$$$</option>
</select>
</div>
<br />
</form>
<button
type="submit"
className="dinner--btn"
onClick={props.addToList}
>
Add to list
</button>
</div>
)
}
服务器端:index.js
const express = require("express") // Set up an express server
const mongoose = require("mongoose") // Import Mongoose library
const cors = require('cors') // Import CORS to communicate with frontend
const app = express() // Initializing our express server
const DinnerModel = require('./models/Dinner')
app.use(express.json()) // Setting up Middleware
app.use(cors())
// Connect to MongoDB
mongoose.connect(
'mongodb+srv://higherstates:<password>@crud.cvewg.mongodb.net/dinner_ideas?retryWrites=true&w=majority',
{
useNewUrlParser: true,
}
)
// Create:
app.post("/insert", async (req, res) => {
const foodName = req.body.foodName
const isVegetarian = req.body.isVegetarian
const priceRange = req.body.priceRange
const dinner = new DinnerModel(
{
foodName: foodName,
isVegetarian: isVegetarian,
priceRange: priceRange,
}
)
try {
await dinner.save()
res.send("data inserted")
} catch(err) {
console.log(err)
}
})
// Read:
app.get("/read", async (req, res) => {
DinnerModel.find({}, (err, result) => {
if (err) {
res.send(err)
}
res.send(result)
})
})
// Update:
app.put("/update", async (req, res) => {
const newFoodName = req.body.newFoodName
const id = req.body.id
try {
await DinnerModel.findById(id, (err, updatedFood) => {
updatedFood.foodName = newFoodName
updatedFood.save()
res.send("update")
}).clone()
} catch(err) {
console.log("The error is: " + err)
}
})
app.delete("/delete/:id", async (req, res) => {
const id = req.params.id
await DinnerModel.findByIdAndRemove(id).exec()
res.send("deleted")
})
// Creating a port:
app.listen(3001, () => {
console.log("Server is up on: http://localhost:3001")
})
FoodListComponent:
export default function FoodListComponent(props) {
return (
<div className="food-list container">
<h1 className="food-list--title">Food List</h1>
<table>
<thead>
<tr>
<th className="th--name">Name</th>
<th className="th--vegetarian">Vegetarian</th>
<th className="th--price">Price</th>
<th className="th--edit">Edit</th>
<th className="th--actions">Action</th>
</tr>
</thead>
<tbody>
{props.foodList.length > 0 && props.foodList.map((val, key) => {
return (
<tr key={key}>
<td>{val.foodName}</td>
<td>
{val.isVegetarian ? <input type="checkbox" checked readOnly /> : <input type="checkbox" disabled="disabled" readOnly />}
</td>
<td>{val.priceRange}</td>
<td>
<input
name="edit"
placeholder="New food name.."
size="15"
maxLength="50"
onChange={(event) => {props.setNewFoodName(event.target.value)}}
>
</input>
</td>
<td>
<button
className="table--btn"
onClick={() => props.updateFood(val._id)}
>
Update
</button>
<button
className="table--btn"
onClick={() => props.deleteFood(val._id)}
>
❌
</button>
</td>
</tr>
)
})}
</tbody>
</table>
</div>
)
}
猫鼬模式:
const mongoose = require('mongoose')
const DinnerSchema = new mongoose.Schema({
foodName: {
type: String,
default: true,
},
isVegetarian: {
type: Boolean,
required: true,
},
priceRange: {
type: String,
required: true,
}
})
const Dinner = mongoose.model("Dinner", DinnerSchema)
module.exports = Dinner
演示如下:
1. 如果我在没有填写**编辑字段**的情况下点击**更新按钮**,它不会做任何事情,但当我刷新页面时数据会消失。
控制台中的错误消息:
https://i.stack.imgur.com/cyAtQ.gif
[演示 gif]
- 应用程序崩溃,这是服务器终端中的错误消息
https://i.stack.imgur.com/bgayZ.jpg
[nodemon 应用程序崩溃错误]
谢谢大家!
// Update:
const updateFood = (id) => {
if(newFoodName){
Axios.put("http://localhost:3001/update", {
id: id,
newFoodName: newFoodName,
})
.catch(error => console.log(`Hey, the error is ${error}`))
}
}
请帮我解决这个问题,因为我搜索了所有 Internet 但找不到答案:(
我正在使用 MERN Stack 制作一个网站,我遇到了一个问题:
Whenever I click Update on the empty input field, my app would crash.
When I catch the error in the Axios update request, it just says Network Error.
请问有没有办法解决这个错误? 也许如果输入字段为空,更新按钮不会触发?
这是我的代码:
// DinnerIdeas.js
import React, { useState, useEffect } from "react"
import './DinnerIdeas.css'
import Axios from "axios"
import FoodListComponent from "../FoodListComponent";
import FormComponent from "../FormComponent";
function DinnerIdeas() {
const [foodName, setFoodName] = useState('')
const [isVegetarian, setVegetarian] = useState(false)
const [priceRange, setPriceRange] = useState('$')
const [newFoodName, setNewFoodName] = useState(null)
const [foodList, setFoodList] = useState([])
// Read:
useEffect(() => {
let unmounted = false
Axios.get("http://localhost:3001/read")
.then((response) => {
if (!unmounted) {
setFoodList(response.data)
}
})
.catch(error => {
console.log(`Hey, the error is ${error}`)
return
})
return () => {
unmounted = true
}
}, [foodList])
// Create:
const addToList = () => {
Axios.post(
"http://localhost:3001/insert",
{
foodName: foodName,
isVegetarian: isVegetarian,
priceRange: priceRange,
}
)
}
// Update:
const updateFood = (id) => {
Axios.put("http://localhost:3001/update", {
id: id,
newFoodName: newFoodName,
})
.catch(error => console.log(`Hey, the error is ${error}`))
}
// Delete:
const deleteFood = (id) => {
Axios.delete(`http://localhost:3001/delete/${id}`)
}
return (
<section className="dinner-ideas">
<FormComponent
setFoodName={setFoodName}
setVegetarian={setVegetarian}
setPriceRange={setPriceRange}
addToList={addToList}
/>
<FoodListComponent
foodList={foodList}
setNewFoodName={setNewFoodName}
updateFood={updateFood}
deleteFood={deleteFood}
/>
</section>
);
}
export default DinnerIdeas;
表单组件:
export default function FormComponent(props) {
return (
<div className="dinner container">
<h1 className="dinner--title">Dinner Ideas</h1>
<form>
<div className="form-group">
<label htmlFor="name">Food name:</label>
<input
type="text"
name="name"
placeholder="Ex: Pesto Pasta"
maxLength="50"
onChange={(event) => {props.setFoodName(event.target.value)}}
required
/>
</div>
<br />
<div className="form-group">
<label htmlFor="vegetarian"> Is this dish Vegetarian?</label>
<select
name="vegetarian"
onChange={(event) => {props.setVegetarian(event.target.value)}}
>
<option value="false">No</option>
<option value="true">Yes</option>
</select>
</div>
<br />
<div className="form-group">
<label htmlFor="price">Price range:</label>
<select
name="price"
onChange={(event) => {props.setPriceRange(event.target.value)}}
>
<option value="$">$</option>
<option value="$$">$$</option>
<option value="$$$">$$$</option>
</select>
</div>
<br />
</form>
<button
type="submit"
className="dinner--btn"
onClick={props.addToList}
>
Add to list
</button>
</div>
)
}
服务器端:index.js
const express = require("express") // Set up an express server
const mongoose = require("mongoose") // Import Mongoose library
const cors = require('cors') // Import CORS to communicate with frontend
const app = express() // Initializing our express server
const DinnerModel = require('./models/Dinner')
app.use(express.json()) // Setting up Middleware
app.use(cors())
// Connect to MongoDB
mongoose.connect(
'mongodb+srv://higherstates:<password>@crud.cvewg.mongodb.net/dinner_ideas?retryWrites=true&w=majority',
{
useNewUrlParser: true,
}
)
// Create:
app.post("/insert", async (req, res) => {
const foodName = req.body.foodName
const isVegetarian = req.body.isVegetarian
const priceRange = req.body.priceRange
const dinner = new DinnerModel(
{
foodName: foodName,
isVegetarian: isVegetarian,
priceRange: priceRange,
}
)
try {
await dinner.save()
res.send("data inserted")
} catch(err) {
console.log(err)
}
})
// Read:
app.get("/read", async (req, res) => {
DinnerModel.find({}, (err, result) => {
if (err) {
res.send(err)
}
res.send(result)
})
})
// Update:
app.put("/update", async (req, res) => {
const newFoodName = req.body.newFoodName
const id = req.body.id
try {
await DinnerModel.findById(id, (err, updatedFood) => {
updatedFood.foodName = newFoodName
updatedFood.save()
res.send("update")
}).clone()
} catch(err) {
console.log("The error is: " + err)
}
})
app.delete("/delete/:id", async (req, res) => {
const id = req.params.id
await DinnerModel.findByIdAndRemove(id).exec()
res.send("deleted")
})
// Creating a port:
app.listen(3001, () => {
console.log("Server is up on: http://localhost:3001")
})
FoodListComponent:
export default function FoodListComponent(props) {
return (
<div className="food-list container">
<h1 className="food-list--title">Food List</h1>
<table>
<thead>
<tr>
<th className="th--name">Name</th>
<th className="th--vegetarian">Vegetarian</th>
<th className="th--price">Price</th>
<th className="th--edit">Edit</th>
<th className="th--actions">Action</th>
</tr>
</thead>
<tbody>
{props.foodList.length > 0 && props.foodList.map((val, key) => {
return (
<tr key={key}>
<td>{val.foodName}</td>
<td>
{val.isVegetarian ? <input type="checkbox" checked readOnly /> : <input type="checkbox" disabled="disabled" readOnly />}
</td>
<td>{val.priceRange}</td>
<td>
<input
name="edit"
placeholder="New food name.."
size="15"
maxLength="50"
onChange={(event) => {props.setNewFoodName(event.target.value)}}
>
</input>
</td>
<td>
<button
className="table--btn"
onClick={() => props.updateFood(val._id)}
>
Update
</button>
<button
className="table--btn"
onClick={() => props.deleteFood(val._id)}
>
❌
</button>
</td>
</tr>
)
})}
</tbody>
</table>
</div>
)
}
猫鼬模式:
const mongoose = require('mongoose')
const DinnerSchema = new mongoose.Schema({
foodName: {
type: String,
default: true,
},
isVegetarian: {
type: Boolean,
required: true,
},
priceRange: {
type: String,
required: true,
}
})
const Dinner = mongoose.model("Dinner", DinnerSchema)
module.exports = Dinner
演示如下:
1. 如果我在没有填写**编辑字段**的情况下点击**更新按钮**,它不会做任何事情,但当我刷新页面时数据会消失。 控制台中的错误消息:
https://i.stack.imgur.com/cyAtQ.gif [演示 gif]
- 应用程序崩溃,这是服务器终端中的错误消息
https://i.stack.imgur.com/bgayZ.jpg [nodemon 应用程序崩溃错误]
谢谢大家!
// Update:
const updateFood = (id) => {
if(newFoodName){
Axios.put("http://localhost:3001/update", {
id: id,
newFoodName: newFoodName,
})
.catch(error => console.log(`Hey, the error is ${error}`))
}
}