我还在学习react,我正在用MERN Stack构建一个应用程序。我试着从表单提交一个帖子,它应该将数据发送到MongoDB Atlas数据库,并在页面上呈现帖子。但是没有数据被发送到数据库,也没有呈现在页面上。我真的不知道问题是从哪里来的,但我有一个axios错误和一个404错误的Chrome浏览器控制台。我不知道是Axios没有连接到后端,还是我的代码有问题。
Form.js
import React, { useState, useEffect } from 'react';
import { TextField, Button, Typography, Paper } from '@material-ui/core';
import FileBase from 'react-file-base64';
import { useDispatch, useSelector } from 'react-redux';
import useStyles from './styles';
import { createPost, updatePost } from '../../actions/posts';
//GET POST CUURENT ID
const Form = ({ currentId, setCurrentId }) => {
const [postData, setPostData] = useState({creator: '', title: '', message: '', tags: '', selectedFile: ''});
const post = useSelector((state) => currentId ? state.posts.find((p) => p._id === currentId) : null);
const classes = useStyles();
const dispatch = useDispatch();
useEffect(() => {
if(post) setPostData(post);
}, [post])
const handleSubmit = (e) => {
e.preventDefault();
if(currentId) {
dispatch(updatePost(currentId, postData));
} else {
dispatch(createPost(postData));
}
clear();
}
const clear = () => {
setCurrentId(null);
setPostData({creator: '', title: '', message: '', tags: '', selectedFile: ''});
}
return (
<Paper className={classes.paper}>
<form autoComplete='off' noValidate className={`${classes.root} ${classes.form}`} onSubmit={handleSubmit}>
<Typography variant='h6'>{ currentId ? 'Edit' : 'Create' } Your Expressions</Typography>
<TextField name='creator' variant='outlined' label='Creator' fullWidth value={postData.creator} onChange={(e) => setPostData({ ...postData, creator: e.target.value })} />
<TextField name='title' variant='outlined' label='Title' fullWidth value={postData.title} onChange={(e) => setPostData({ ...postData, title: e.target.value })} />
<TextField name='message' variant='outlined' label='Message' fullWidth value={postData.message} onChange={(e) => setPostData({ ...postData, message: e.target.value })} />
<TextField name='tags' variant='outlined' label='Tags' fullWidth value={postData.tags} onChange={(e) => setPostData({ ...postData, tags: e.target.value })} />
<div className={classes.fileInput}><FileBase type="file"multiple={false} onDone={({base64}) => setPostData({ ...postData, selectedFile: base64 })} />
</div>
<Button className={classes.buttonSubmit} variant='contained' color='primary' size='large' type='submit' fullWidth>Submit</Button>
<Button variant='outlined' color='primary' size='large' onClick={clear} fullWidth>Clear</Button>
</form>
</Paper>
);
}
export default Form;
Server/index.js
import express from 'express';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
import cors from 'cors';
import postRoutes from './routes/posts.js'
const app = express();
app.use('/posts', postRoutes);
app.use(bodyParser.json({ limit: "30mb", extended: true}));
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true}));
app.use(cors());
app.use('/posts', postRoutes);
const CONNECTION_URL = 'mongodb+srv://Akan-
modanwealth:[email protected]/?retryWrites=true&w=majority';
const PORT = process.env.PORT || 5000;
mongoose.connect(CONNECTION_URL).then(()=>{console.log('...')})
.then(() => app.listen(PORT, () => console.log('Server running on port:
${PORT}')))
.catch((error) => console.log(error.message));
App.js
import React, { useState, useEffect } from 'react';
import { Container, AppBar, Typography, Grow, Grid } from '@material-ui/core';
import { useDispatch } from 'react-redux';
import { getPosts } from './actions/posts';
import Posts from './components/Posts/Posts';
import Form from './components/Form/Form';
import expressions from './images/expressions.jpg';
import useStyles from './styles';
const App = () => {
const [currentId, setCurrentId] = useState(null);
const classes = useStyles();
const dispatch = useDispatch();
useEffect(() => {
dispatch(getPosts);
}, [currentId, dispatch]);
return (
<Container maxWidth="lg">
<AppBar className={classes.appBar} position="static" >
<Typography className={classes.heading} variant="h2" align="center">Expressions</Typography>
<img className={classes.image} src={expressions} alt="expressions" height="80" width="60" />
</AppBar>
<Grow in>
<Container>
<Grid container justifyContent="space-between" alignItems="stretch" spacing={3}>
<Grid item xs={12} sm={7}>
<Posts setCurrentId={setCurrentId} />
</Grid>
<Grid item xs={12} sm={4}>
<Form currentId={currentId} setCurrentId={setCurrentId} />
</Grid>
</Grid>
</Container>
</Grow>
</Container>
);
}
export default App;
api/index.js
import axios from 'axios';
const url = 'http://localhost:5000/posts';
export const fetchPosts = () => axios.get(url);
export const createPost = (newPost) => axios.post(url, newPost);
export const updatePost = (id, updatedPost) => axios.patch(`${url}/${id}`,
updatedPost);
routes/posts.js
import express from 'express';
import { getPosts, createPost, updatePost} from
'../controllers/posts.js';
const router = express.Router();
router.get('/', getPosts);
router.get('/', createPost);
router.patch('/:id', updatePost)
export default router;
2条答案
按热度按时间4c8rllxm1#
所以有几件事。首先,您可能在MongoDB URI中暴露了密码,所以我会立即更改它。第二,你为什么要运行
app.use("/posts", postRoutes);
两次?最后,它看起来像你发布到
/posts
,但你没有指定之后的路由。你没有共享你的路由,但是从外观上看,/posts
使用了你的路由文件夹中的所有路由。你需要给予一个特定的路线,比如/posts/create
之类的。否则,你只是说用你所有的中间件向对象发出POST请求,而node.js不知道使用哪个中间件。nkhmeac62#
确保您的API正在运行。npm start