如何使用Node.js和ReactJS构建一个基本的CRUD应用程序

如何使用Node.js和ReactJS构建一个基本的CRUD应用程序

在本文中,我们将从头开始创建一个基本的学生应用程序。

应用程序功能:

  • 创建一个新的学生
  • 更新现有的学生
  • 显示学生列表
  • 删除一个学生

该项目中的REST API:

REST API URL
GET http://localhost:4000/students
GET /students/update-student/id
POST /students/create-student
PUT /students/update-student/id
DELETE /students/delete-student/id

首先,我们将使用React.js处理应用程序的前端部分。

创建React应用程序并安装模块

步骤1: 让我们开始使用React构建前端部分。要创建一个新的React应用程序,请输入以下代码到终端并按Enter键。

npx create-react-app mern-stack-crud

步骤2: 进入React项目文件夹。

cd mern-stack-crud

步骤3: 要运行React应用程序,请运行以下命令:

npm start

此命令会在以下URL中在浏览器中打开React应用程序: http://localhost:3000/

步骤4: 要构建React应用程序,我们需要安装一些外部模块。

NPM 详情
React-Bootstrap React-Bootstrap与React一同发展和成长,成为您UI的绝佳选择。
React-Router-Dom React-Router-Dom使您能够在React App中实现路由功能。
Axios 这是一个基于promise的HTTP客户端,用于网络请求。
Formik React中构建表单的优秀库。
Yup Yup是用于表单验证的JavaScript架构生成器。

要安装,请在终端上运行以下代码。

npm i react-bootstrap@next bootstrap@5.1.0 react-router-dom axios formik yup 

步骤5:创建简单的React组件 – 在这一步中,我们将创建一些React组件来管理学生数据。

前往 src 文件夹,创建一个名为 Components 的文件夹,并在该目录下创建以下组件。

  • StudentForm.js - 可重用的学生表单
  • create-student.component.js - 负责创建新学生
  • edit-student.component.js - 负责更新学生数据
  • student-list.component.js - 负责显示所有学生
  • StudentTableRow.js - 负责显示单个学生

项目结构: 它将如下所示

如何使用Node.js和ReactJS构建一个基本的CRUD应用程序

步骤6: 创建学生表单 – 在这一步中,我们将使用Formik和React-Bootstrap构建一个可复用的学生表单。这个表单包含了输入学生详细信息所需的所有字段。我们还使用Yup进行了客户端表单验证。将来,我们将使用这个组件来创建和更新学生信息。前往 src/Components/StudentForm.js 并写入以下代码。

StudentForm.js

import React from "react"; 
import * as Yup from "yup"; 
import { Formik, Form, Field, ErrorMessage } from "formik"; 
import { FormGroup, FormControl, Button } from "react-bootstrap"; 
  
const StudentForm = (props) => { 
  const validationSchema = Yup.object().shape({ 
    name: Yup.string().required("Required"), 
    email: Yup.string() 
      .email("You have enter an invalid email address") 
      .required("Required"), 
    rollno: Yup.number() 
      .positive("Invalid roll number") 
      .integer("Invalid roll number") 
      .required("Required"), 
  }); 
  console.log(props); 
  return ( 
    <div className="form-wrapper"> 
      <Formik {...props} validationSchema={validationSchema}> 
        <Form> 
          <FormGroup> 
            <Field name="name" type="text" 
                className="form-control" /> 
            <ErrorMessage 
              name="name"
              className="d-block invalid-feedback"
              component="span"
            /> 
          </FormGroup> 
          <FormGroup> 
            <Field name="email" type="text" 
                className="form-control" /> 
            <ErrorMessage 
              name="email"
              className="d-block invalid-feedback"
              component="span"
            /> 
          </FormGroup> 
          <FormGroup> 
            <Field name="rollno" type="number" 
                className="form-control" /> 
            <ErrorMessage 
              name="rollno"
              className="d-block invalid-feedback"
              component="span"
            /> 
          </FormGroup> 
          <Button variant="danger" size="lg" 
            block="block" type="submit"> 
            {props.children} 
          </Button> 
        </Form> 
      </Formik> 
    </div> 
  ); 
}; 
  
export default StudentForm; 

步骤7:创建新学生: 在这一步中,我们将创建一个组件来添加一个新学生。我们已经创建了一个 StudentForm 组件来输入学生的详细信息。现在是使用这个组件的时候了。进入 src/Components/create-student.component.js 并编写以下代码。

create-student.component.js

// CreateStudent Component for add new student 
  
// Import Modules 
import React, { useState, useEffect } from "react"; 
import axios from 'axios'; 
import StudentForm from "./StudentForm"; 
  
// CreateStudent Component 
const CreateStudent = () => { 
  const [formValues, setFormValues] =  
    useState({ name: '', email: '', rollno: '' }) 
  // onSubmit handler 
  const onSubmit = studentObject => { 
    axios.post( 
'http://localhost:4000/students/create-student',  
    studentObject) 
      .then(res => { 
        if (res.status === 200) 
          alert('Student successfully created') 
        else
          Promise.reject() 
      }) 
      .catch(err => alert('Something went wrong')) 
  } 
    
  // Return student form 
  return( 
    <StudentForm initialValues={formValues}  
      onSubmit={onSubmit}  
      enableReinitialize> 
      Create Student 
    </StudentForm> 
  ) 
} 
  
// Export CreateStudent Component 
export default CreateStudent

步骤8:更新学生详情: 在这一部分中,我们将创建一个组件来更新学生的详情。我们有一个可重用的 StudentForm 组件,让我们再次使用它。我们将获取学生详情来重新初始化表单。打开 src/Components/edit-student.component.js 并编写以下代码。

edit-student.component.js

// EditStudent Component for update student data 
  
// Import Modules 
import React, { useState, useEffect } from "react"; 
import axios from "axios"; 
import StudentForm from "./StudentForm"; 
  
// EditStudent Component 
const EditStudent = (props) => { 
  const [formValues, setFormValues] = useState({ 
    name: "", 
    email: "", 
    rollno: "", 
  }); 
    
  //onSubmit handler 
  const onSubmit = (studentObject) => { 
    axios 
      .put( 
        "http://localhost:4000/students/update-student/" + 
          props.match.params.id, 
        studentObject 
      ) 
      .then((res) => { 
        if (res.status === 200) { 
          alert("Student successfully updated"); 
          props.history.push("/student-list"); 
        } else Promise.reject(); 
      }) 
      .catch((err) => alert("Something went wrong")); 
  }; 
  
  // Load data from server and reinitialize student form 
  useEffect(() => { 
    axios 
      .get( 
        "http://localhost:4000/students/update-student/" 
        + props.match.params.id 
      ) 
      .then((res) => { 
        const { name, email, rollno } = res.data; 
        setFormValues({ name, email, rollno }); 
      }) 
      .catch((err) => console.log(err)); 
  }, []); 
  
  // Return student form 
  return ( 
    <StudentForm 
      initialValues={formValues} 
      onSubmit={onSubmit} 
      enableReinitialize 
    > 
      Update Student 
    </StudentForm> 
  ); 
}; 
  
// Export EditStudent Component 
export default EditStudent;

步骤9:显示学生列表: 在这一步中,我们将构建一个组件来在表格中显示学生的详细信息。我们将获取学生的数据,并遍历每个学生创建一个表格行。请转到 src/Components/student-list.component.js 并编写以下代码。

student-list.component.js

import React, { useState, useEffect } from "react"; 
import axios from "axios"; 
import { Table } from "react-bootstrap"; 
import StudentTableRow from "./StudentTableRow"; 
  
const StudentList = () => { 
  const [students, setStudents] = useState([]); 
  
  useEffect(() => { 
    axios 
      .get("http://localhost:4000/students/") 
      .then(({ data }) => { 
        setStudents(data); 
      }) 
      .catch((error) => { 
        console.log(error); 
      }); 
  }, []); 
  
  const DataTable = () => { 
    return students.map((res, i) => { 
      return <StudentTableRow obj={res} key={i} />; 
    }); 
  }; 
  
  return ( 
    <div className="table-wrapper"> 
      <Table striped bordered hover> 
        <thead> 
          <tr> 
            <th>Name</th> 
            <th>Email</th> 
            <th>Roll No</th> 
            <th>Action</th> 
          </tr> 
        </thead> 
        <tbody>{DataTable()}</tbody> 
      </Table> 
    </div> 
  ); 
}; 
  
export default StudentList;

步骤10:显示单个学生: 在这一步中,我们将返回表格行,该行负责显示学生数据。进入 src/Components/StudentTableRow.js 并编写以下代码。

StudentTableRow.js

import React from "react"; 
import { Button } from "react-bootstrap"; 
import { Link } from "react-router-dom"; 
import axios from "axios"; 
  
const StudentTableRow = (props) => { 
  const { _id, name, email, rollno } = props.obj; 
  
  const deleteStudent = () => { 
    axios 
      .delete( 
"http://localhost:4000/students/delete-student/" + _id) 
      .then((res) => { 
        if (res.status === 200) { 
          alert("Student successfully deleted"); 
          window.location.reload(); 
        } else Promise.reject(); 
      }) 
      .catch((err) => alert("Something went wrong")); 
  }; 
  
  return ( 
    <tr> 
      <td>{name}</td> 
      <td>{email}</td> 
      <td>{rollno}</td> 
      <td> 
        <Link className="edit-link" 
          to={"/edit-student/" + _id}> 
          Edit 
        </Link> 
        <Button onClick={deleteStudent}  
          size="sm" variant="danger"> 
          Delete 
        </Button> 
      </td> 
    </tr> 
  ); 
}; 
  
export default StudentTableRow;

步骤11:编辑App.js: 最后,包含菜单使我们的MERN Stack CRUD应用程序可以进行路由。去 src/App.js 并写入以下代码。

App.js

// Import React 
import React from "react"; 
  
// Import Bootstrap 
import { Nav, Navbar, Container, Row, Col }  
        from "react-bootstrap"; 
import "bootstrap/dist/css/bootstrap.css"; 
  
// Import Custom CSS 
import "./App.css"; 
  
// Import from react-router-dom 
import { BrowserRouter as Router, Switch, 
    Route, Link } from "react-router-dom"; 
  
// Import other React Component 
import CreateStudent from  
    "./Components/create-student.component"; 
import EditStudent from  
    "./Components/edit-student.component"; 
import StudentList from  
    "./Components/student-list.component"; 
  
// App Component 
const App = () => { 
  return ( 
    <Router> 
      <div className="App"> 
        <header className="App-header"> 
          <Navbar bg="dark" variant="dark"> 
            <Container> 
              <Navbar.Brand> 
                <Link to={"/create-student"}  
                  className="nav-link"> 
                  React MERN Stack App 
                </Link> 
              </Navbar.Brand> 
  
              <Nav className="justify-content-end"> 
                <Nav> 
                  <Link to={"/create-student"}  
                    className="nav-link"> 
                    Create Student 
                  </Link> 
                </Nav> 
  
                <Nav> 
                  <Link to={"/student-list"}  
                    className="nav-link"> 
                    Student List 
                  </Link> 
                </Nav> 
              </Nav> 
            </Container> 
          </Navbar> 
        </header> 
  
        <Container> 
          <Row> 
            <Col md={12}> 
              <div className="wrapper"> 
                <Switch> 
                  <Route exact path="/" 
                    component={CreateStudent} /> 
                  <Route path="/create-student" 
                    component={CreateStudent} /> 
                  <Route path="/edit-student/:id" 
                    component={EditStudent} /> 
                  <Route path="/student-list" 
                    component={StudentList} /> 
                </Switch> 
              </div> 
            </Col> 
          </Row> 
        </Container> 
      </div> 
    </Router> 
  ); 
}; 
  
export default App;

步骤12:添加样式 – 转到 src/App.css 并编写以下代码。

App.css

.wrapper { 
  padding-top: 30px; 
} 
  
body h3 { 
  margin-bottom: 25px; 
} 
  
.navbar-brand a { 
  color: #ffffff; 
} 
  
.form-wrapper, 
.table-wrapper { 
  max-width: 500px; 
  margin: 0 auto; 
} 
  
.table-wrapper { 
  max-width: 700px; 
} 
  
.edit-link { 
  padding: 7px 10px; 
  font-size: 0.875rem; 
  line-height: normal; 
  border-radius: 0.2rem; 
  color: #fff; 
  background-color: #28a745; 
  border-color: #28a745; 
  margin-right: 10px; 
  position: relative; 
  top: 1px; 
} 
  
.edit-link:hover { 
  text-decoration: none; 
  color: #ffffff; 
} 
  
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button, 
input::-webkit-inner-spin-button { 
  -webkit-appearance: none; 
  margin: 0; 
} 
  
/* Firefox */
input[type=number] { 
  -moz-appearance: textfield; 
}

现在,我们已经成功为我们的 mern-stack-app 创建了前端部分。 **现在,让我们来构建后端部分。在进入下一部分之前,先看一下前端部分在没有后端的情况下如何工作。

运行应用程序的步骤: 打开终端并输入以下命令。

npm start

输出:

如何使用Node.js和ReactJS构建一个基本的CRUD应用程序

现在我们将开始处理应用程序的后端部分。我们将在我们的 mern-stack-crud 文件夹中创建一个文件夹,用于管理服务器服务,如数据库、模型、架构、路由和API,将这个文件夹命名为 backend

步骤1: 运行命令以创建 backend 文件夹作为服务器,并进入其中。

mkdir backend && cd backend

步骤2:创建package.json – 接下来,我们需要创建一个单独的 package.json 文件来管理我们的 mern-stack-crud 应用程序的服务器。

npm init -y

访问 backend/package.json 文件将如下所示。替换 test 属性如下:

 ~~"test": "echo \"Error: no test specified\" && exit 1" ~~
"start": "nodemon server.js"

步骤3:安装Node依赖库 – 安装以下的Node依赖库。

NPM 详情
Express Node.js框架,帮助创建强大的REST API。
body-parser 从请求流中提取整个body部分,并在req.body上公开它。
cors 这是一个Node.js包,帮助启用Access-Control-Allow-Origin CORS标头。
mongoose 它是一个用于创建强大Web应用程序的NoSQL数据库。

安装上述依赖项,请在终端上运行以下代码。

npm install express body-parser cors mongoose

您可以将nodemon安装为开发依赖项,以自动化服务器重新启动过程。

npm i -D nodemon

后端项目结构

如何使用Node.js和ReactJS构建一个基本的CRUD应用程序

步骤4:设置MongoDB数据库 – 在这一步中,我们将为我们的应用程序设置一个MongoDB数据库。在开始之前,请确保您的系统上安装了最新版本的MongoDB。在 backend 文件夹内创建一个名为 database 的文件夹。在 database 文件夹内创建一个名为 db.js 的文件。转到 backend/database/db.js 并编写以下代码。

db.js

module.exports = { 
  db: 'mongodb://localhost:27017/reactdb'
};

我们声明了MongoDB数据库并将其命名为 reactdb

步骤5:定义Mongoose模式 – 现在,为与MongoDB数据库交互创建MongoDB模式。在 backend 文件夹内创建一个名为 models 的文件夹以保存与模式相关的文件,并在其中创建一个名为 Student.js 的文件来定义MongoDB模式。转到 backend/models/Student.js 并编写以下代码。

Student.js

const mongoose = require('mongoose'); 
const Schema = mongoose.Schema; 
  
let studentSchema = new Schema({ 
  name: { 
    type: String 
  }, 
  email: { 
    type: String 
  }, 
  rollno: { 
    type: Number 
  } 
}, { 
    collection: 'students'
  }) 
  
module.exports = mongoose.model('Student', studentSchema)

我们在student Schema中声明了name,email和rollno字段及其相应的数据类型。

步骤6:使用ExpressJS创建路由 – 在这一步中,我们使用Express和Node.js设置了一些路由(REST APIs)用于创建、读取、更新和删除。这些路由将帮助我们管理在 mern-stack-crud 应用中的数据。在backend文件夹中创建一个名为routes的文件夹,并在其中创建一个名为student.routes.js的文件。在这个文件中定义我们的路由。

mkdir routes && cd routes && touch student.route.js

然后,进入 backend/routes/student.route.js 文件并编写以下代码。

student.route.js

let mongoose = require("mongoose"), 
  express = require("express"), 
  router = express.Router(); 
  
// Student Model 
let studentSchema = require("../models/Student"); 
  
// CREATE Student 
router.post("/create-student", (req, res, next) => { 
  studentSchema.create(req.body, (error, data) => { 
    if (error) { 
      return next(error); 
    } else { 
      console.log(data); 
      res.json(data); 
    } 
  }); 
}); 
  
// READ Students 
router.get("/", (req, res) => { 
  studentSchema.find((error, data) => { 
    if (error) { 
      return next(error); 
    } else { 
      res.json(data); 
    } 
  }); 
}); 
  
// UPDATE student 
router 
  .route("/update-student/:id") 
  // Get Single Student 
  .get((req, res) => { 
    studentSchema.findById( 
        req.params.id, (error, data) => { 
      if (error) { 
        return next(error); 
      } else { 
        res.json(data); 
      } 
    }); 
  }) 
  
  // Update Student Data 
  .put((req, res, next) => { 
    studentSchema.findByIdAndUpdate( 
      req.params.id, 
      { 
        $set: req.body, 
      }, 
      (error, data) => { 
        if (error) { 
          return next(error); 
          console.log(error); 
        } else { 
          res.json(data); 
          console.log("Student updated successfully !"); 
        } 
      } 
    ); 
  }); 
  
// Delete Student 
router.delete("/delete-student/:id",  
(req, res, next) => { 
  studentSchema.findByIdAndRemove( 
      req.params.id, (error, data) => { 
    if (error) { 
      return next(error); 
    } else { 
      res.status(200).json({ 
        msg: data, 
      }); 
    } 
  }); 
}); 
  
module.exports = router;

步骤7:配置server.js – 我们几乎已经创建了所有的内容来实现我们的mern-stack-crud应用。现在,在backend文件夹的根目录下创建server.js文件。进入backend/server.js并写入以下代码。

server.js

let express = require('express'); 
let mongoose = require('mongoose'); 
let cors = require('cors'); 
let bodyParser = require('body-parser'); 
let dbConfig = require('./database/db'); 
  
// Express Route 
const studentRoute = require('../backend/routes/student.route') 
  
// Configure mongoDB Database 
mongoose.set('useNewUrlParser', true); 
mongoose.set('useFindAndModify', false); 
mongoose.set('useCreateIndex', true); 
mongoose.set('useUnifiedTopology', true); 
  
// Connecting MongoDB Database 
mongoose.Promise = global.Promise; 
mongoose.connect(dbConfig.db).then(() => { 
  console.log('Database successfully connected!') 
}, 
  error => { 
    console.log('Could not connect to database : ' + error) 
  } 
) 
  
const app = express(); 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ 
  extended: true
})); 
app.use(cors()); 
app.use('/students', studentRoute) 
  
  
// PORT 
const port = process.env.PORT || 4000; 
const server = app.listen(port, () => { 
  console.log('Connected to port ' + port) 
}) 
  
// 404 Error 
app.use((req, res, next) => { 
  res.status(404).send('Error 404!') 
}); 
  
app.use(function (err, req, res, next) { 
  console.error(err.message); 
  if (!err.statusCode) err.statusCode = 500; 
  res.status(err.statusCode).send(err.message); 
});

现在,我们已经成功创建了我们的后端 mern-stack-app

我们的最终项目目录结构:

如何使用Node.js和ReactJS构建一个基本的CRUD应用程序

现在,启动MongoDB数据库服务器运行服务器。

运行应用程序的步骤: 在一个终端中打开并运行以下命令,通过在 backend 文件夹中保持Nodemon服务器的运行。

npm start

如果一切正常运行,你将在终端屏幕上看到以下输出。

如何使用Node.js和ReactJS构建一个基本的CRUD应用程序

最终输出:

如何使用Node.js和ReactJS构建一个基本的CRUD应用程序

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程