React之简易笔记本

此文使用React实现简易笔记本,包括环境配置,前台界面和后台应用等内容。其中后台应用主要功能是数据库操作,前台应用的主要功能是显示,增加,删除,更新数据 ,效果如下所示:

一、数据库设计

MongoDB是一个基于分布式文件存储 的数据库,具有高性能、易部署、易使用,存储数据方便等特点。此项目所采用的是Mongodb数据库,集合文件主要包含id,message,timestamps三个字段,其数据文件如下所示:

1、数据结构

javascript 复制代码
//data.js
//引入mongoose模块
const mongoose = require('mongoose');
//引入schema
const Schema = mongoose.Schema;
//数据结构
const DataSchema = new Schema(
    {
        id: Number,
        message: String
    },
    { timestamps: true }
);
//返回schema ,便于通过Node.js使用
module.exports = mongoose.model('Data', DataSchema);

2、注册免费数据库

在浏览器中访问Mongodb官网(MongoDB: The Developer D,如ata Platform | MongoDB),如图所示:

单击如图所示画红线部分,按照提示先进行注册,注册界面如下所示:

注册后出现登录界面如下所示:

登录后按照提示进行操作,注意选择AWS的512MB 自由数据库,并新建访问用户名为guest,完成设置后,如图所示:

单击红色按钮,出现如图所示,使当前MO为右侧512MB自由数据库。

单击黄色按钮,选择第一项,nodejs连接,出现如图所示:

连接代码如上红色所示,连接数据库代码如下:

javascript 复制代码
//连接数据库
const uri = "mongodb+srv://guest:<guest用户访问密码>@cluster0.gulaw.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0";
mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });
const db = mongoose.connection;
//检查数据库连接是否成功
db.on('error', console.error.bind(console, 'connection error:'));
//显示连接成功
db.once('open', function() {
  console.log('Connected to MongoDB')
})

获取数据代码,如下所示:

javascript 复制代码
const Data=require('./data');
Data.find().exec()
        .then((data) => {
        return res.json({ success: true, data: data });
   })
   .catch((err) => {
        return res.json({ success: false, error: err });
   })

新增数据代码,如下所示:

javascript 复制代码
let data = new Data();
  const { id, message } = req.body;
  if ( (!id && id !==0) || !message) {
      return res.json({
          success: false,
          error: 'INVALID INPUTS'
      });
  }
  data.message = message;
  data.id = id;
  data.save()
      .then(() => res.json({ success: true }))
      .catch(err => res.json({ success: false, error: err }));

删除数据数据代码,如下所示:

javascript 复制代码
const { id } = req.body;
    Data.findOneAndDelete(id)
      .then(data=>res.json({ success: true }))
      .catch(err =>res.json({ success: false, error: err }));

更新数据代码,如下所示:

javascript 复制代码
    const { id, update } = req.body;
    Data.findOneAndUpdate({_id: id},update)
          .then(data=>{
            return res.json({ success: true });
          })
          .catch(err =>{
            return res.json({ success: false, error: err });
          });

以上是Mongodb数据库在线使用方法和访问代码,访问数据库采用mongoose库。

二、后台应用

项目后台采用nodejs+express+mongooseb库的方式运行,侦听端口为3000,其中:

'/getData' 为获取数据,访问方式get

'/putData' 为新增数据,访问方式post

'/deleteData' 为删除数据,访问方式delete

'/updateData' 为更新数据,访问方式post

注意:1、采用bodyParser的json编码方式。

2、采用cors库解决访问跨域问题。

3、需安装相应库,其中mongoose为数据库访问库,morgan库为日志库。

后台代码如下所示:

javascript 复制代码
//定义Mongodb连接
const mongoose=require('mongoose');
//引入express
const express = require('express');
//引入body-parser
const bodyParser = require('body-parser');
//引入morgan
const logger= require('morgan');
const Data=require('./data');
const API_PORT = 3000;
//express实例
const app = express();
const cors = require('cors');
// 允许所有源访问
app.use(cors());
//路由
const router = express.Router();
//使用body-parser
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//开启日志
app.use(logger('dev'));

//连接数据库
/*
const { MongoClient, ServerApiVersion } = require('mongodb');
const uri = "mongodb+srv://guest:qqq123456@cluster0.gulaw.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0";
// Create a MongoClient with a MongoClientOptions object to set the Stable API version
const client = new MongoClient(uri, {
  serverApi: {
    version: ServerApiVersion.v1,
    strict: true,
    deprecationErrors: true,
  }
});
async function run() {
  try {
    // Connect the client to the server	(optional starting in v4.7)
    await client.connect();
    // Send a ping to confirm a successful connection
    await client.db("admin").command({ ping: 1 });
    console.log("Pinged your deployment. You successfully connected to MongoDB!");
  } finally {
    // Ensures that the client will close when you finish/error
    await client.close();
  }
}
run().catch(console.dir);
*/
//连接数据库
const uri = "mongodb+srv://guest:qqq123456@cluster0.gulaw.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0";
mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });
const db = mongoose.connection;
//检查数据库连接是否成功
db.on('error', console.error.bind(console, 'connection error:'));
//显示连接成功
db.once('open', function() {
  console.log('Connected to MongoDB')
})

//获取数据的方法
router.get('/getData', (req, res) => {
   console.log('/getData已经执行');
   Data.find().exec()
        .then((data) => {
        return res.json({ success: true, data: data });
   })
   .catch((err) => {
        return res.json({ success: false, error: err });
   })
});

//添加数据的方法
//用于向数据库添加新的数据
router.post('/putData', (req, res) => {
  let data = new Data();
  const { id, message } = req.body;
  if ( (!id && id !==0) || !message) {
      return res.json({
          success: false,
          error: 'INVALID INPUTS'
      });
  }
  data.message = message;
  data.id = id;
  data.save()
      .then(() => res.json({ success: true }))
      .catch(err => res.json({ success: false, error: err }));
})


//数据更新的方法
//用于对数据库已有数据进行更新
router.post('/updateData', (req, res) => {
    const { id, update } = req.body;
    console.log('updateData已经执行');
    console.log(id,update);
    Data.findOneAndUpdate({_id: id},update)
          .then(data=>{
            return res.json({ success: true });
          })
          .catch(err =>{
            return res.json({ success: false, error: err });
          });
});
  
//删除数据的方法
//用于对数据库已有数据进行删除
router.delete('/deleteData', (req, res) => {
    const { id } = req.body;
    Data.findOneAndDelete(id)
      .then(data=>res.json({ success: true }))
      .catch(err =>res.json({ success: false, error: err }));
});

//对http请求增加/api路由
app.use('/api', router);
//开启端口 
app.listen(API_PORT, () => console.log(`LISTENING ON PORT ${API_PORT}`));

三、前台应用

前台采用React +antd组件方式编写, 整个界面分为四部分,第一部分为List显示笔记内容,第二部分为Card ,包含一个输入框和新增按钮,第三部分为Card ,主要功能是删除笔记,包含一个输入框和删除按钮,第四部分为Card,主要功能是更新笔记,包含两个输入框和更新按钮。前端采用React自带的fetch从服务器中获取笔记,使用axios从服务器中,新增笔记、删除笔记、更新笔记,代码如下所示:

javascript 复制代码
import React,{ Component } from 'react'
//引入axios用于发送异步请求获取数据
import axios from 'axios'
//引入antd组件库
import { Button ,Input,List,Avatar,Card } from 'antd'
//引入样式库
class App extends Component {
  //初始化state
  state = {
    data: [],
    id:0,
    message: null,
    IntervalIsSet: false,
    idToDelete: null,
    idToUpdate: null,
    objectToUpdate: null
  }
  //获取数据
  getDataFromDb=()=>{
    fetch("http://localhost:3000/api/getData")
      .then(data=> data.json())
      .then(res=>this.setState({data: res.data}))
  };
  //新增数据
  putDataToDB=(message)=>{
    let cureentIds=this.state.data.map((data)=>data.id);
    let idToBeAdded=0;
    while(cureentIds.includes(idToBeAdded)){
      idToBeAdded++;
    }
    axios.post("http://localhost:3000/api/putData",{
      id:idToBeAdded,
      message:message
    })
    console.log('message',message);
  }
  //删除数据
  deleteFromDB=(idToDelete)=>{
     let objIdToDelete=null;
     this.state.data.forEach((data)=>{
      if(data.id===idToDelete){
        objIdToDelete=data._id;
      }
     });

     axios.delete("http://localhost:3000/api/deleteData",{data:{id:objIdToDelete}});
  };
  //更新数据
  updateDB=(idToUpdate,objectToUpdate)=>{
    
    let objIdToUpdate=null;
    this.state.data.forEach((data)=>{
      if(data.id==idToUpdate){
        objIdToUpdate=data._id;
      }
    });


    axios.post("http://localhost:3000/api/updateData",{
      id:objIdToUpdate,
      update: {message: objectToUpdate}
    });
  }
  //组件挂载后执行
  componentDidMount() {
      this.getDataFromDb();
      if(!this.state.IntervalIsSet){
        let interval=setInterval(this.getDataFromDb,1000);
        this.setState({IntervalIsSet: interval});
      }
  }
  //组件卸载前执行
  componentWillUnmount() {
    if(this.state.IntervalIsSet){
      clearInterval(this.state.IntervalIsSet);
      this.setState({IntervalIsSet: null});
    }
  }
  //组件更新后执行
  render() {
      const {data=[]}=this.state;
      console.log('data',data);

      return (<div style={{width:990,margin:20,backgroundColor:'#ccc'}}>
        <List 
          itemLayout="horizontal"
          dataSource={data}
          renderItem={item => (
            <List.Item>
              <List.Item.Meta
                avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
                title={<span>创建时间:{item.createdAt}</span>}
                description={<span>{item.id}:{item.message}</span>}
              />
            </List.Item>
          )}
        />

        <Card
          title="新增笔记"
          style={{padding: 10,margin: 10}}
        >
        <Input 
            placeholder="请输入笔记内容"  
            style={{width: 200}} 
            onChange={e=>this.setState({message: e.target.value})}
        />
        <Button 
          type="primary"
          style={{margin: 20}}
          onClick={()=>this.putDataToDB(this.state.message)}
        >新增</Button>
        </Card>
        
        <Card 
          title="删除笔记"
          style={{padding: 10,margin: 10}}>
        <Input 
          placeholder="填写所需删除ID"  
          style={{width: 200}} 
          onChange={e=>this.setState({idToDelete: e.target.value})}
        />
        <Button 
            type="primary"
            style={{margin: 20}}
            onClick={()=>this.deleteFromDB(this.state.idToDelete)}
          >删除</Button>
        </Card>
    
        <Card
            title="更新笔记"
            style={{padding: 10,margin: 10}}
         >
        <Input 
            placeholder="填写所需更新ID"  
            style={{width: 200,marginRight: 10}} 
            onChange={e=>this.setState({idToUpdate: e.target.value})}
        />
        <Input 
            placeholder="填写所需更新内容"  
            style={{width: 200}} 
            onChange={e=>this.setState({objectToUpdate: e.target.value})}
        />
        <Button 
          type="primary"
          style={{margin: 20}}
          onClick={()=>this.updateDB(this.state.idToUpdate,this.state.objectToUpdate)}
          >更新</Button>
        </Card>   
    </div>
    );
  }
}

export default App

本文简要讲述了采用mogoose+express+react方式,完成一个简易的笔记本项目,其中在线数据库存由于网络问题,非常不稳定,在调试时需要非常注意,另外,mongoose库访问数据库的代码书写方式新,旧有所不同,跨域访问也应该是在调试时,特别加以留心。

相关推荐
T^T尚3 小时前
uniapp H5上传图片前压缩
前端·javascript·uni-app
出逃日志4 小时前
JS的DOM操作和事件监听综合练习 (具备三种功能的轮播图案例)
开发语言·前端·javascript
XIE3924 小时前
如何开发一个脚手架
前端·javascript·git·npm·node.js·github
GISer_Jing4 小时前
React渲染相关内容——渲染流程API、Fragment、渲染相关底层API
javascript·react.js·ecmascript
山猪打不过家猪4 小时前
React(五)——useContecxt/Reducer/useCallback/useRef/React.memo/useMemo
前端·javascript·react.js
前端青山4 小时前
React事件处理机制详解
开发语言·前端·javascript·react.js
科技D人生4 小时前
Vue.js 学习总结(14)—— Vue3 为什么推荐使用 ref 而不是 reactive
前端·vue.js·vue ref·vue ref 响应式·vue reactive
对卦卦上心4 小时前
React-useEffect的使用
前端·javascript·react.js
练习两年半的工程师4 小时前
React的基本知识:事件监听器、Props和State的区分、改变state的方法、使用回调函数改变state、使用三元运算符改变state
前端·javascript·react.js
啵咿傲4 小时前
在React中实践一些软件设计思想 ✅
前端·react.js·前端框架