尝试使用空输入字段提交时,React 应用程序崩溃
Posted
技术标签:
【中文标题】尝试使用空输入字段提交时,React 应用程序崩溃【英文标题】:React app crashed when trying to submit with empty input field 【发布时间】:2022-01-20 11:01:30 【问题描述】:请帮我解决这个问题,因为我搜索了所有互联网但找不到答案:(
我正在使用 MERN Stack 制作网站,但遇到了一个问题:
每当我点击空输入字段上的更新时,我的应用就会崩溃。
当我在 Axios 更新请求中发现错误时,它只是说 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")
)
食物列表组件:
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>
)
Mongoose 架构:
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. 如果我在没有填写**Edit field**的情况下点击**Update button**,它不会做任何事情,但是当我刷新页面时数据会消失。 控制台中的错误消息:https://i.stack.imgur.com/cyAtQ.gif [演示gif]
-
应用程序崩溃,这是服务器终端中的错误消息
https://i.stack.imgur.com/bgayZ.jpg [nodemon 应用崩溃错误]
谢谢大家!
【问题讨论】:
您是否尝试修复 CORS 错误,因为您可能向其他域发送请求而不是您的 react 应用程序? 我认为错误很明显。在 mongo 模式中,名称是required
并且您发送的是一个空值。如果您打算允许空值,请修改架构以允许它。或使用客户端验证阻止 API 调用在值为空时发生
似乎 foodName 是必需的,并且您没有对 foorName 进行任何空值检查
@programoholic 我将架构从required: true
更改为default: undefined
。现在更新按钮将不再提交空值,而是上面的 FormComponent,当我单击“添加到列表”时,它会将空值输入到数据库中。有什么办法可以解决这个问题?
@RamRana 嗨,我们应该把空检查放在哪里?你能告诉我更多关于这方面的信息吗?谢谢:)
【参考方案1】:
// 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`))
【讨论】:
以上是关于尝试使用空输入字段提交时,React 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
在 React 中提交表单时如何获取要显示的名称和 uuid
用ant-design在react js中提交后清除表单输入字段值