Node.js 如何在React with useState中生成API post
我正在使用MaterialUI开发一个Mern堆栈应用程序。我有一个事件模型,一个事件有很多评论。我现在面临的挑战是如何使用Node.js 如何在React with useState中生成API post,node.js,reactjs,material-ui,Node.js,Reactjs,Material Ui,我正在使用MaterialUI开发一个Mern堆栈应用程序。我有一个事件模型,一个事件有很多评论。我现在面临的挑战是如何使用基于功能的组件对事件发表评论。我以前在基于类的组件中使用过这种方法,但现在我决定将代码更改为使用基于函数的组件,但我不知道如何实现这一点。控制台中出现的错误是404未找到。如何设置useState以使用Axios正确发送写入数据 import React, { useState, useEffect } from "react"; import { Li
基于功能的组件
对事件发表评论。我以前在基于类的组件中使用过这种方法,但现在我决定将代码更改为使用基于函数的组件,但我不知道如何实现这一点。控制台中出现的错误是404未找到
。如何设置useState以使用Axios正确发送写入数据
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import axios from "axios";
import AddComingWithModal from "../components/coming-with-
modal.component";
import { makeStyles } from "@material-ui/core/styles";
import clsx from "clsx";
import Card from "@material-ui/core/Card";
import CardHeader from "@material-ui/core/CardHeader";
import CardMedia from "@material-ui/core/CardMedia";
import CardContent from "@material-ui/core/CardContent";
import CardActions from "@material-ui/core/CardActions";
import Collapse from "@material-ui/core/Collapse";
import Avatar from "@material-ui/core/Avatar";
import IconButton from "@material-ui/core/IconButton";
import Typography from "@material-ui/core/Typography";
import { red } from "@material-ui/core/colors";
import FavoriteIcon from "@material-ui/icons/Favorite";
import ShareIcon from "@material-ui/icons/Share";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import MoreVertIcon from "@material-ui/icons/MoreVert";
import { useTheme } from "@material-ui/core/styles";
import useMediaQuery from "@material-ui/core/useMediaQuery";
import Grid from "@material-ui/core/Grid";
import moment from "moment";
import FilledInput from "@material-ui/core/FilledInput";
import FormControl from "@material-ui/core/FormControl";
import FormHelperText from "@material-ui/core/FormHelperText";
import Input from "@material-ui/core/Input";
import InputLabel from "@material-ui/core/InputLabel";
import OutlinedInput from "@material-ui/core/OutlinedInput";
export default function EventAndComments(props) {
const url = props.location.pathname;
const theme = useTheme();
const [eventComments, setTileData] = useState([]);
const useStyles = makeStyles((theme) => ({
root: {
maxWidth: 850,
},
media: {
height: 0,
paddingTop: "86%", // 16:9
display: "flex",
flexDirection: "column",
alignItems: "center",
},
expand: {
transform: "rotate(0deg)",
marginLeft: "auto",
transition: theme.transitions.create("transform", {
duration: theme.transitions.duration.shortest,
}),
},
expandOpen: {
transform: "rotate(180deg)",
},
avatar: {
backgroundColor: red[500],
},
}));
const classes = useStyles();
const [expanded, setExpanded] = React.useState(false);
const handleExpandClick = () => {
setExpanded(!expanded);
};
useEffect(() => {
axios
.get(
"http://localhost:9000/events/" +
props.match.params.id +
"/eventcomments"
)
.then((response) => {
setTileData(response.data);
})
.catch(function (error) {
console.log(error);
});
}, []);
const nowIso = new Date();
const getTitle = (startDateTs, endDateTs) => {
const now = Date.parse(nowIso);
if (endDateTs <= now) {
return "Started:" + " " + moment(startDateTs).format("LLLL");
}
if (startDateTs < now && endDateTs > now) {
return "Live:" + " " + moment(startDateTs).format("LLLL");
}
return "Starting:" + " " + moment(startDateTs).format("LLLL");
};
const getEnded = (startDateTs, endDateTs) => {
const now = Date.parse(nowIso);
if (endDateTs <= now) {
return "Ended:" + " " + moment(startDateTs).format("LLLL");
}
if (startDateTs < now && endDateTs > now) {
return "Will End:" + " " + moment(startDateTs).format("LLLL");
}
return "Ends:" + " " + moment(startDateTs).format("LLLL");
};
const [setEventComment, setName] = React.useState("");
const handleChange = (event) => {
setName({ ...setEventComment, [event.target.name]: event.target.value
});
};
const onSubmit = (e) => {
e.preventDefault();
axios
.post(
"http://localhost:9000/events/" + props.match.params.id,
setEventComment
)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
};
return (
<Grid
container
spacing={0}
direction="column"
alignItems="center"
justify="center"
style={{ minHeight: "100vh" }}
>
<Card className={classes.root}>
<h3
style={{
background: " #800000",
color: "white",
textAlign: "center",
}}
className={classes.cardheader}
>
{eventComments.title}
</h3>
<CardHeader
avatar={
<Avatar aria-label="recipe" className={classes.avatar}>
CB
</Avatar>
}
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
title={getTitle(
Date.parse(eventComments.startingDate),
Date.parse(eventComments.closingDate)
)}
subheader={getEnded(
Date.parse(eventComments.startingDate),
Date.parse(eventComments.closingDate)
)}
style={{ background: "#DCDCDC" }}
/>
<CardMedia
className={classes.media}
image={eventComments.eventImage}
title="Paella dish"
/>
<CardContent>
<Typography variant="body2" color="textSecondary" component="p">
{eventComments.description}
</Typography>
</CardContent>
</Card>
<form
className={classes.root}
noValidate
autoComplete="off"
onSubmit={onSubmit}
>
<FormControl>
<InputLabel htmlFor="component-simple">Name</InputLabel>
<Input
id="component-simple"
value={setEventComment.name}
onChange={handleChange}
/>
</FormControl>
<FormControl variant="outlined">
<InputLabel htmlFor="component-outlined">Name</InputLabel>
<OutlinedInput
id="component-outlined"
value={setEventComment.description}
onChange={handleChange}
label="Name"
/>
</FormControl>
<input
type="submit"
className="btn btn-outline-warning btn-block mt-4"
/>
</form>
</Grid>
import React,{useState,useffect}来自“React”;
从“react router dom”导入{Link};
从“axios”导入axios;
从“./组件/附带-
模态组件”;
从“@material ui/core/styles”导入{makeStyles}”;
从“clsx”导入clsx;
从“@物料界面/核心/卡片”导入卡片;
从“@material ui/core/CardHeader”导入CardHeader;
从“@material ui/core/CardMedia”导入CardMedia;
从“@material ui/core/CardContent”导入CardContent;
从“@material ui/core/CardActions”导入CardActions;
从“@material ui/core/Collapse”导入折叠;
从“@material ui/core/Avatar”导入化身;
从“@material ui/core/IconButton”导入图标按钮;
从“@material ui/core/Typography”导入排版;
从“@material ui/core/colors”导入{red}”;
从“@material ui/icons/Favorite”导入收藏夹图标;
从“@material ui/icons/Share”导入ShareIcon;
从“@material ui/icons/ExpandMore”导入ExpandMoreIcon;
从“@material ui/icons/MoreVert”导入MoreVertIcon;
从“@material ui/core/styles”导入{useTheme}”;
从“@material ui/core/useMediaQuery”导入useMediaQuery;
从“@material ui/core/Grid”导入网格;
从“时刻”中导入时刻;
从“@material ui/core/FilledInput”导入FilledInput;
从“@material ui/core/FormControl”导入FormControl;
从“@material ui/core/FormHelperText”导入FormHelperText;
从“@material ui/core/Input”导入输入;
从“@material ui/core/InputLabel”导入InputLabel;
从“@material ui/core/OutlinedInput”导入OutlinedInput;
导出默认函数EventAndComments(道具){
const url=props.location.pathname;
const theme=useTheme();
const[eventComments,setTileData]=useState([]);
const useStyles=makeStyles((主题)=>({
根目录:{
最大宽度:850,
},
媒体:{
高度:0,,
paddingTop:“86%,//16:9
显示:“flex”,
flexDirection:“列”,
对齐项目:“中心”,
},
扩展:{
变换:“旋转(0度)”,
marginLeft:“自动”,
转换:theme.transitions.create(“转换”{
持续时间:theme.transitions.duration.shortest,
}),
},
expandOpen:{
变换:“旋转(180度)”,
},
化身:{
背景颜色:红色[500],
},
}));
const classes=useStyles();
const[expanded,setExpanded]=React.useState(false);
常量handleExpandClick=()=>{
setExpanded(!expanded);
};
useffect(()=>{
axios
.得到(
"http://localhost:9000/events/" +
props.match.params.id+
“/eventcomments”
)
。然后((响应)=>{
setTileData(响应数据);
})
.catch(函数(错误){
console.log(错误);
});
}, []);
const nowIso=新日期();
常量getTitle=(开始日期、结束日期)=>{
const now=Date.parse(nowIso);
如果(现在结束日期){
返回“实时:”+“+时刻(开始日期)。格式(“LLLL”);
}
返回“开始:”+“+时刻(开始日期)。格式(“LLLL”);
};
const getend=(开始日期、结束日期)=>{
const now=Date.parse(nowIso);
如果(现在结束日期){
return“Will End:”+“+时刻(startDateTs).format(“LLLL”);
}
返回“结束:”+“+时刻(开始日期)。格式(“LLLL”);
};
const[setEventComment,setName]=React.useState(“”);
常量handleChange=(事件)=>{
setName({…setEventComment,[event.target.name]:event.target.value
});
};
const onSubmit=(e)=>{
e、 预防默认值();
axios
.邮政(
"http://localhost:9000/events/“+props.match.params.id,
setEventComment
)
.然后(功能(响应){
控制台日志(响应);
})
.catch(函数(错误){
console.log(错误);
});
};
返回(
{eventComments.title}
{eventComments.description}
名称
名称
));
}问题不是来自useState,您可以调用
axios.post(
"http://localhost:9000/events/" + props.match.params.id,
setEventComment
)
您得到的错误是url
"http://localhost:9000/events/“+props.match.params.id
不存在。我不知道你应该怎么发送身份证
"http://localhost:9000/events?id=“+props.match.params.id
或者其他事情,但根据您的日志,这就是问题所在:
从浏览器控制台。xhr.js:178篇文章http://localhost:9000/events/5f35e9c686c3a9132b5067b9 404(未找到)错误:请求失败,状态代码为404请尝试
控制台日志记录您的props.match.params.id
并检查其设置是否正确。@bertdida我这样做了,它返回了正确的id。我的问题是,看看我如何设置useState,我的代码正确吗?在我看来,您使用的useStates
s是正确的。哪个API调用从浏览器控制台返回404
<代码>xhr.js:178帖子http://localhost:9000/events/5f35e9c686c3a9132b5067b9 404(未找到)
错误:请求失败,状态代码为404
@bertdidayou是正确的,我在URL中遗漏了一些单词,我感觉很糟糕,因为这让我在@Damien停留了很长时间