📌  相关文章
📜  如何使用 Node.js 和 ReactJS 构建一个基本的 CRUD 应用程序?(1)

📅  最后修改于: 2023-12-03 14:52:00.436000             🧑  作者: Mango

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

在本文中,我们将学习如何使用 Node.js 和 ReactJS 构建一个基本的 CRUD 应用程序。首先,我们将学习什么是 CRUD,然后我们将了解如何使用 Node.js 和 ReactJS 构建一个基本的 CRUD 应用程序,从而更好地理解它。

什么是 CRUD?

CRUD是创建(Create)、读取(Read)、更新(Update)和删除(Delete)操作的缩写。 这些是软件开发中最常见的操作之一。

在开发应用程序时,开发人员不仅需要执行这些操作,还需要将这些操作的结果存储在数据库中。在这个教程中,我们将使用 MongoDB 作为我们的数据库。

构建基本的 CRUD 应用程序
步骤1:设置 Node.js 和 MongoDB

首先,我们需要安装 Node.js 和 MongoDB。我们可以从官方网站下载 Node.js 和 MongoDB,并根据需要进行安装。

步骤2:创建一个新项目并初始化依赖项

使用以下命令来创建一个新的项目目录,并在其中创建一个 package.json 文件:

mkdir project-name
cd project-name
npm init -y

接下来,运行以下命令安装依赖项:

npm install express mongoose body-parser cors
步骤3:启动服务器

我们将创建一个名为 server.js 的文件,该文件将是我们的服务器。请使用以下代码创建该文件:

const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');

const app = express();
const PORT = 4000;

app.use(cors());
app.use(bodyParser.json());

mongoose.connect('mongodb://127.0.0.1:27017/crud', { useNewUrlParser: true });
const connection = mongoose.connection;

connection.once('open', () => {
  console.log('MongoDB database connection established successfully');
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

在上面的代码中,我们首先导入了所需的依赖项,然后创建了一个 app 实例,用于处理所有的 HTTP 请求。我们还使用 cors 中间件来启用跨域资源共享。接下来,我们使用 mongoose 连接到 MongoDB 数据库,并在连接成功时打印一条消息。

最后,我们将应用程序监听在端口号 4000 上,并在成功启动时输出一条消息。

运行以下命令启动服务器:

node server.js
步骤4:创建 Mongoose 模型

我们需要在 MongoDB 数据库中创建一个 collection,用于存储数据。为此,我们需要创建一个 Mongoose 模型,该模型将负责与数据库交互。

在项目根目录中创建一个名为 models 的文件夹,并在其中创建一个名为 item.js 的文件。请使用以下代码创建该文件:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const itemSchema = new Schema({
  name: { type: String, required: true },
  description: { type: String, required: true },
  quantity: { type: Number, required: true },
}, {
  timestamps: true,
});

const Item = mongoose.model('Item', itemSchema);

module.exports = Item;

在上面的代码中,我们首先导入 mongoose,并使用 Schema 类创建一个模式。模式描述了要在模型中使用的属性。我们的模式包含三个属性:name、description 和 quantity。

接下来,我们为模型添加 timestamps 选项,以便在每次创建或更新文档时自动更新 createdAt 和 updatedAt 字段。最后,我们创建一个名为 Item 的模型,并将其导出。

步骤5:添加路由

我们需要在服务器上添加路由,用于处理来自客户端的请求。请使用以下代码创建一个名为 items.js 的文件,并运行以下命令来安装所需的依赖项:

npm install multer
const router = require('express').Router();
const multer = require('multer');

const Item = require('../models/item');

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'uploads/');
  },
  filename: (req, file, cb) => {
    cb(null, `${Date.now()}-${file.originalname}`);
  },
});

const upload = multer({ storage });

router.route('/').get((req, res) => {
  Item.find()
    .then((items) => res.json(items))
    .catch((err) => res.status(400).json(`Error: ${err}`));
});

router.route('/:id').get((req, res) => {
  Item.findById(req.params.id)
    .then((item) => res.json(item))
    .catch((err) => res.status(400).json(`Error: ${err}`));
});

router.route('/add').post(upload.single('image'), (req, res) => {
  const { name, description, quantity } = req.body;
  const newItem = new Item({
    name,
    description,
    quantity,
    image: req.file.filename,
  });
  newItem
    .save()
    .then(() => res.json('Item added!'))
    .catch((err) => res.status(400).json(`Error: ${err}`));
});

router.route('/:id').delete((req, res) => {
  Item.findByIdAndDelete(req.params.id)
    .then(() => res.json('Item deleted.'))
    .catch((err) => res.status(400).json(`Error: ${err}`));
});

router.route('/update/:id').post((req, res) => {
  Item.findById(req.params.id)
    .then((item) => {
      const { name, description, quantity } = req.body;
      item.name = name;
      item.description = description;
      item.quantity = quantity;
      item
        .save()
        .then(() => res.json('Item updated!'))
        .catch((err) => res.status(400).json(`Error: ${err}`));
    })
    .catch((err) => res.status(400).json(`Error: ${err}`));
});

module.exports = router;

在上面的代码中,我们首先导入路由和 multer 中间件,并使用 Item 模型来处理来自客户端的请求。我们使用 multer 中间件来上传文件,并将结果存储在 uploads 目录中。

我们定义了以下路由:

  • GET /items - 获取所有项目
  • GET /items/:id - 按 ID 检索项目
  • POST /items/add - 添加新项目
  • DELETE /items/:id - 删除项目
  • POST /items/update/:id - 更新项目

GET /items 路由使用 Item.find 方法从数据库中检索所有项目,并将结果返回给客户端。

GET /items/:id 路由使用 Item.findById 方法从数据库中按 ID 检索项目,并将结果返回给客户端。

POST /items/add 路由使用 multer 中间件上传文件,并使用 Item 模型创建新项目。我们从客户端数据中获取 name、description 和 quantity,以及从上传的文件中获取 image 名称。

DELETE /items/:id 路由使用 Item.findByIdAndDelete 方法从数据库中删除项目。

POST /items/update/:id 路由使用 Item.findById 方法检索要更新的项目,并在此基础上执行更新操作。

请记住,我们需要在 server.js 文件中将路由添加到应用程序中。请使用以下代码将该路由添加到您的 server.js 文件中:

const itemRouter = require('./routes/items');

app.use('/items', itemRouter);
步骤6:添加 ReactJS UI

我们需要为我们的应用程序创建一个简单的 UI,以便用户可以与其交互。请使用以下命令创建一个名为 client 的新目录,并在其中初始化 React 应用程序:

npx create-react-app client

接下来,需要在 client/src 目录下创建一个名为 api.js 的文件:

import axios from 'axios';

const API_URL = 'http://localhost:4000';

export const getItems = () => axios.get(`${API_URL}/items`);
export const getItemById = (id) => axios.get(`${API_URL}/items/${id}`);
export const addItem = (name, description, quantity, image) => {
  const fd = new FormData();
  fd.append('name', name);
  fd.append('description', description);
  fd.append('quantity', quantity);
  fd.append('image', image);
  return axios.post(`${API_URL}/items/add`, fd);
};
export const deleteItemById = (id) => axios.delete(`${API_URL}/items/${id}`);
export const updateItemById = (id, name, description, quantity) =>
  axios.post(`${API_URL}/items/update/${id}`, { name, description, quantity });

在上面的代码中,我们首先导入 axios 库,并定义了 API_URL 常量。接下来,我们创建了一组方法,用于通过 HTTP 请求与服务端进行交互。

getItems 方法使用 GET 请求从服务器获取所有项目。

getItemById 方法使用 GET 请求从服务器按 ID 检索项目。

addItem 方法使用 POST 请求将新项目添加到服务器。我们将 data 对象转换为 FormData,并将其作为请求主体发送到服务器。

deleteItemById 方法使用 DELETE 请求从服务器删除项目。

updateItemById 方法使用 POST 请求将更新后的项目数据发送到服务器,并在此基础上执行更新操作。

我们还需要在 UI 中使用这些方法。因此,请打开 src/App.js 文件,并使用以下代码替换其中的内容:

import React, { useState, useEffect } from 'react';
import './App.css';
import * as api from './api';

function App() {
  const [items, setItems] = useState([]);
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [quantity, setQuantity] = useState('');
  const [image, setImage] = useState(null);

  const handleSubmit = (event) => {
    event.preventDefault();
    api.addItem(name, description, quantity, image).then(() => fetchItems());
  };

  const handleDelete = (id) => {
    api.deleteItemById(id).then(() => fetchItems());
  };

  const fetchItems = () => {
    api.getItems().then((response) => setItems(response.data));
  };

  useEffect(() => {
    fetchItems();
  }, []);

  const Item = ({ item }) => (
    <div className="Item">
      <img src={`http://localhost:4000/uploads/${item.image}`} alt={item.name} />
      <h2>{item.name}</h2>
      <p>{item.description}</p>
      <span>Quantity: {item.quantity}</span>
      <button onClick={() => handleDelete(item._id)}>Delete</button>
    </div>
  );

  const ItemForm = () => (
    <form onSubmit={handleSubmit}>
      <h2>Add New Item</h2>
      <input type="text" placeholder="Name" value={name} onChange={(e) => setName(e.target.value)} />
      <input type="text" placeholder="Description" value={description} onChange={(e) => setDescription(e.target.value)} />
      <input type="number" placeholder="Quantity" value={quantity} onChange={(e) => setQuantity(e.target.value)} />
      <input type="file" onChange={(e) => setImage(e.target.files[0])} />
      <button type="submit">Add</button>
    </form>
  );

  return (
    <div className="App">
      <ItemForm />
      <div className="Items">
        {items.map((item) => (
          <Item key={item._id} item={item} />
        ))}
      </div>
    </div>
  );
}

export default App;

在上面的代码中,我们首先导入 useState 和 useEffect 钩子,并使用它们来管理 UI 状态。我们创建了一个名为 items 的列表,并使用此列表渲染所有项目。

我们还创建了一个名为 Item 的组件,用于渲染每个项目。该组件使用 img 元素、h2 元素、p 元素、span 元素和删除按钮将项目的详细信息渲染到 UI 中。

我们还定义了 ItemForm 组件,用于添加新项目。该组件使用表单元素、输入元素和提交按钮,与 addItem 方法配合使用。

最后,我们在 App 组件中使用 ItemForm 和 Items 组件,并定义了 handleSubmit、handleDelete 和 fetchItems 等方法,用于处理 UI 交互。

步骤7:启动应用程序

现在,我们已经完成了 Node.js 后端和 ReactJS 前端的构建。打开两个终端窗口,并分别切换到项目根目录和 client 目录,并使用以下命令分别启动 Node.js 服务器和 ReactJS 应用程序:

node server.js
npm start

在浏览器中打开 http://localhost:3000,您应该能够看到应用程序的 UI。现在,您可以使用该应用程序执行 CRUD 操作!

总结

通过本文,我们学习了如何使用 Node.js 和 ReactJS 构建一个基本的 CRUD 应用程序。我们了解了 CRUD 的意义,并学习了如何使用 Express 和 Mongoose 在 Node.js 中实现 API。我们还使用 ReactJS 创建了一个简单的 UI,该 UI允许用户使用应用程序执行 CRUD 操作。