![](/img/trans.png)
[英]react is posting data to console, but data is not successfully making it mysql database
[英]How to load data imediately after posting successfully in react with useEffect on Reactjs
我正在开发一个具有事件 Model 的 Mern 堆栈应用程序,该事件有很多评论。 我想要的是在成功创建评论后加载评论,但我收到一条错误消息。
React Hook "useEffect" is called in function "onSubmit" which is neither a React function component or a custom React Hook function
。
当我在基于类的组件中执行此操作时有效,但我将代码更改为基于 function 的组件。 如何在成功创建后立即加载评论?
这是我的代码。
export default function EventAndComments(props) {
const EventComment = (props) => (
<CardContent>
<Typography variant="body2" color="textSecondary" component="p">
{props.comment.name}
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
{props.comment.description}
</Typography>
</CardContent>
);
const theme = useTheme();
const [events, setEventData] = useState([]);
const [comments, setCommentData] = 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) => {
setEventData(response.data);
})
.catch(function (error) {
console.log(error);
});
}, []);
useEffect(() => {
axios
.get(
"http://localhost:9000/events/" +
props.match.params.id +
"/eventcomments"
)
.then((response) => {
setCommentData(response.data.eventcomments);
})
.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 [eventDescription, setEventComment] = React.useState("");
const [name, setName] = React.useState("");
const handleChange = (parameter) => (event) => {
if (parameter === "name") {
setName(event.target.value);
}
if (parameter === "description") {
setEventComment(event.target.value);
}
};
const onSubmit = useCallback(
(e) => {
e && e.preventDefault();
axios
.post(
"http://localhost:9000/events/" +
props.match.params.id +
"/eventcomment",
{ name: name, description: eventDescription }
)
.then(function (response) {
setCommentData(response.data.eventcomments);
})
.catch(function (error) {
console.log(error);
});
},
[props.match.params.id, name, eventDescription]
);
let eventCommentList = comments.map((comment, k) => (
<EventComment comment={comment} key={k} />
));
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}
>
{events.title}
</h3>
<CardHeader
avatar={
<Avatar aria-label="recipe" className={classes.avatar}>
CB
</Avatar>
}
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
title={getTitle(
Date.parse(events.startingDate),
Date.parse(events.closingDate)
)}
subheader={getEnded(
Date.parse(events.startingDate),
Date.parse(events.closingDate)
)}
style={{ background: "#DCDCDC" }}
/>
<CardMedia
className={classes.media}
image={events.eventImage}
title="Paella dish"
/>
<CardContent>
<Typography variant="body2" color="textSecondary" component="p">
{events.description}
</Typography>
</CardContent>
</Card>
<CardContent>{eventCommentList}</CardContent>
<form
className={classes.root}
noValidate
autoComplete="off"
onSubmit={onSubmit}
>
<FormControl>
<InputLabel htmlFor="component-simple">Name</InputLabel>
<Input
id="component-simple"
value={name}
onChange={handleChange("name")}
label="Name"
/>
</FormControl>
<FormControl variant="outlined">
<InputLabel htmlFor="component-outlined">Description</InputLabel>
<OutlinedInput
id="component-outlined"
value={eventDescription}
onChange={handleChange("description")}
label="Description"
/>
</FormControl>
<input
type="submit"
className="btn btn-outline-warning btn-block mt-4"
/>
</form>
</Grid>
);
}
`
您只能在顶层使用钩子,请阅读 “钩子规则” 。
在您的情况下,为什么不在请求成功时更新 state?
const onSubmit = (e) => {
e.preventDefault();
axios
.post(
"http://localhost:9000/events/" + props.match.params.id + "/eventcomment",
{ name: name, description: eventDescription }
)
.then(function (response) {
setCommentData(response.data.eventcomments);
})
.catch(function (error) {
console.log(error);
});
};
export default function EventAndComments(props) {
const EventComment = (props) => (
<CardContent>
<Typography variant="body2" color="textSecondary" component="p">
{props.comment.name}
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
{props.comment.description}
</Typography>
</CardContent>
);
const theme = useTheme();
const [events, setEventData] = useState([]);
const [comments, setCommentData] = 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);
};
// ---- there is new -------
const fetchCommentList = useCallback(()=>{
return axios
.get(
"http://localhost:9000/events/" +
props.match.params.id +
"/eventcomments"
)
.then((response) => {
setCommentData(response.data.eventcomments);
})
.catch(function (error) {
console.log(error);
});
},[props.match.params.id])
useEffect(() => {
// first time to fetch data
fetchCommentList()
}, [fetchCommentList]);
// -----------------------------
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 [eventDescription, setEventComment] = React.useState("");
const [name, setName] = React.useState("");
const handleChange = (parameter) => (event) => {
if (parameter === "name") {
setName(event.target.value);
}
if (parameter === "description") {
setEventComment(event.target.value);
}
};
// -------- there is new -----------
const onSubmit = useCallback(
(e) => {
e && e.preventDefault();
axios
.post(
"http://localhost:9000/events/" +
props.match.params.id +
"/eventcomment",
{ name: name, description: eventDescription }
)
.then(function (response) {
// what content of the `response` ?
// setCommentData(response.data.eventcomments);
// there is a problem
// is your `post` http request can get all comments?
// how about your `get` http request ?
// normally `get` http request to get resource
// `post` http request to create new resource
// so there should be use your `get` request to fetch new data
fetchCommentList()
})
.catch(function (error) {
console.log(error);
});
},
[props.match.params.id, name, eventDescription]
);
// -------------------------
const eventCommentList = comments.map((comment, k) => (
<EventComment comment={comment} key={k} />
));
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}
>
{events.title}
</h3>
<CardHeader
avatar={
<Avatar aria-label="recipe" className={classes.avatar}>
CB
</Avatar>
}
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
title={getTitle(
Date.parse(events.startingDate),
Date.parse(events.closingDate)
)}
subheader={getEnded(
Date.parse(events.startingDate),
Date.parse(events.closingDate)
)}
style={{ background: "#DCDCDC" }}
/>
<CardMedia
className={classes.media}
image={events.eventImage}
title="Paella dish"
/>
<CardContent>
<Typography variant="body2" color="textSecondary" component="p">
{events.description}
</Typography>
</CardContent>
</Card>
<CardContent>{eventCommentList}</CardContent>
<form
className={classes.root}
noValidate
autoComplete="off"
onSubmit={onSubmit}
>
<FormControl>
<InputLabel htmlFor="component-simple">Name</InputLabel>
<Input
id="component-simple"
value={name}
onChange={handleChange("name")}
label="Name"
/>
</FormControl>
<FormControl variant="outlined">
<InputLabel htmlFor="component-outlined">Description</InputLabel>
<OutlinedInput
id="component-outlined"
value={eventDescription}
onChange={handleChange("description")}
label="Description"
/>
</FormControl>
<input
type="submit"
className="btn btn-outline-warning btn-block mt-4"
/>
</form>
</Grid>
);
}
================================更新==================
试试这个方法; )
const [comments, setCommentData] = useState([]);
const onSubmit = useCallback(
(e) => {
e && e.preventDefault();
axios
.post(
"http://localhost:9000/events/" +
props.match.params.id +
"/eventcomment",
{ name: name, description: eventDescription }
)
.then(function (response) {
console.log(response);
setCommentData(response.data.eventcomments);
})
.catch(function (error) {
console.log(error);
});
},
[props.match.params.id, name, eventDescription],
)
useEffect(()=>{
onSubmit()
},[onSubmit])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.