如何使用json-server模拟React的数据源

434 阅读10分钟

使用json-server模拟React的数据源

开发人员在构建React.js项目时需要一些带有端点的快速使用的数据源。这些数据源提供了测试数据,以测试软件包是否正常工作。

数据源是数据诞生的初始位置。它可能是一个数据库、平面文件、来自物理设备的实时测量数据,等等。

数据源主要被用作数据库管理系统管理的数据库,如MySQL、Postgres、SQL等。这种方法的问题是,在原型开发过程中,如果应用程序的原型不符合预期,它将很快被抛弃。

快速原型开发方法是一种敏捷的系统开发方法,它允许人们创建一个原型来测试和验证需求规格文件(RSD)的要求。

这种开发是通过几次迭代进行的。原型可以作为主要系统使用,也可以被抛弃,这样就可以在原型的基础上开发另一个主要系统。通过建立一个原型,可以避免额外的设置和配置,如果它们很快被丢弃。

这个过程产生了一个需求,即创建一个可以快速设置和丢弃的数据源,但它可以执行与DBMS相同的功能。它还应该足够小,有较少的存储需求,以产生预期的正确和准确的结果。

json-server 库可以解决这样的数据源问题。json-server 库在React应用中可以快速安装、配置、使用和废弃。在这篇文章中,你将学习如何在React.js应用程序中对上述包进行以下操作。

主要收获

到最后,读者将学到以下内容。

  • 什么是json-server 库?
  • 在React.js应用程序中设置json-server 库。
  • 将应用程序连接到库中。
  • 将该库作为数据源,代替实际的DBMS。
  • 从应用程序中移除依赖关系并丢弃原型。

先决条件

需要以下条件。

  • 在机器上设置好的IDE或文本编辑器。
  • 一个稳定的互联网连接。
  • 已经设置好的React开发环境。
  • React开发技能。

关于文章中要做的事情的简要信息如下。

  • 学习关于JSON服务器包的简介。
  • 创建一个React.js应用程序。
  • 将其设置为允许来自链接的API数据。
  • 对应用程序进行样式设计。
  • 在机器上安装JSON服务器。
  • 将JSON服务器设置为一个模拟数据库服务器。
  • 在项目中配置JSON服务器的数据源。
  • 运行应用程序。

了解json-server包

JSON服务器允许几乎所有类型的后端请求和响应,如GET,POST,PUT,PATCH, 和DELETE 方法。它有访问存储在模拟数据库文件(JSON)中的数据项的路由。

几个例子是:GET /posts ,获取所有的帖子,PUT /posts/1 ,更新第一个帖子,或者DELETE /posts/1 ,删除第一个帖子。该模块允许对数据库进行其他操作,例如。

进行数据库过滤

例如 -GET /posts?title=json-server&author=riroGET/comments?author.name=riro 。这些端点分别用json-servertitleauthor 的名称rirocommentsauthor 的名称riro 来过滤posts

为获取的结果添加分页功能

例子 -GET /posts?_page=9&_limit=23.这个请求将从9 页面获取帖子,并且页面限制被设置为23

对数据库中的项目进行排序

例子 -GET/posts/5/comments?_sort=votes,likes&_order=desc,asc.这个请求根据voteslikes 分别以升序和降序的方式对comments 进行排序。

对数据进行分片操作

例子 -GET/posts/4/comments?_start=20&_limit=10.这个请求从评论号20 开始,截断comments 后的评论10

操作员

当排除一个值时,我们使用_ne ,而要基于一个值进行过滤,我们使用_like 。一个例子GET /posts/4/comments?_ne=sad 请求,排除了任何值为sad 的评论,而GET \author_like=chris 搜索与chris 相关的名称的authors (使用 RegEx)。

在数据库中进行全文搜索

例子 -GET/posts?q=tomcat.这个请求在所有存储的记录中搜索值tomcat

与数据库中的项目建立关系

使用_embed 包含子资源,使用_expand 包含父资源,可以创建嵌套资源。一个例子是GET /comments/1?_expand=post ,它包括了名称为post 的父资源。

获取完整的数据库

例子 -GET\db 。这个GET ,获取了指定数据库的所有数据库项目。

构建React.js应用程序

在本节中,将创建一个React.js应用程序。我们将建立一个预算规划的应用程序,从列表中添加或删除它们。该应用程序使用JSON对象从数据源保存和检索数据。

让我们开始吧。打开应该创建应用程序的文件夹,运行这个命令。

npx create-react-app react-budget-tracker

文件夹结构应该是这样的。

.
├── node_modules
├── public
├── src
│   └── components
│       ├── About.js
│       ├── AddBudget.js
│       ├── Budget.js
│       ├── Budgets.js
│       ├── Button.js
│       ├── Footer.js
│       └── Header.js
│   ├── App.js
│   ├── index.css
│   ├── index.js
│   └── reportWebVitals.js
├── .eslintcache
├── .gitignore
├── db.json
├── package.json
├── package-lock.json
├── README.md
└── yarn.lock

头部组件

顾名思义,Header.js 文件包含头部分。

  • Header.js ,其代码如下所示。
import PropTypes from 'prop-types'
import { useLocation } from 'react-router-dom'
import Button from './Button'

const Header = ({ title, onAdd, showAdd }) => {
  const location = useLocation()

  /*The header has a title and a button that opens up a window to add the budget or close the window*/
  return (
    <header className='header'>

    <!-- The header has a title -->
    <h1>{title}</h1>
    {location.pathname === '/' && (
      <Button
        color={showAdd ? 'red' : 'green'}
        text={showAdd ? 'Close' : 'Add'}
        onClick={onAdd}
        />
    )}
    </header>
  )
}

/*Set the title*/
Header.defaultProps = {
  title: 'Budget Tracker',
}

Header.propTypes = {
  title: PropTypes.string.isRequired,
}

/*Export the header*/
export default Header

这段代码为网页创建了一个简单的页眉,并允许它用于添加以下内容。

  • 一个页眉标题。
  • 一个添加预算项目和删除预算项目的按钮。
  • 设置按钮的颜色。
  • 设置标题值并导出页眉。

页脚组件

  • Footer.js 文件中,以下将是代码。
import { Link } from 'react-router-dom'

/*Add a footer to the application*/
const Footer = () => {
  return (
    /*It has a copyright and a link to the about page*/
      <footer>
        <p>Copyright &copy; 2021</p>
          <Link to='/about'>About</Link>
      </footer>
  )
}

export default Footer

该代码会生成一个包含版权和关于页面链接的页脚。

按钮组件

Button.js 增加了一个可重复使用的按钮组件,用于多个点击动作。例如,这个按钮可以打开Add 表格和Close 表格。

import PropTypes from 'prop-types'

/*A button that allows one to set its color, the text it displays and the function it executes on a click event*/
const Button = ({ color, text, onClick }) => {
  return (
    <button
      onClick={onClick}
        style={{ backgroundColor: color }}
        className='btn'
    >
      {text}
    </button>
  )
}

Button.defaultProps = {
  color: 'steelblue',
}

Button.propTypes = {
  text: PropTypes.string,
  color: PropTypes.string,
  onClick: PropTypes.func,
}

export default Button

该代码生成了一个按钮,允许人们设置其。

  • 颜色。
  • 文本,以及
  • 当它被点击时要执行的功能。

关于网页组件

  • 现在,添加一个关于网页,包含与作者有关的细节。
import { Link } from 'react-router-dom'

/*Generates a simple about page that has a simple button to go back to the main page*/
const About = () => {
return (
<div>
<h4>Version 1.0.0</h4>
  <Link to='/'>
    <button type="button" className={"btn btn-secondary"}>
    Go Back
    </button>
  </Link>
</div>
)
}

export default About

预算.js文件

Budget.js 文件使人们能够与显示在屏幕上的服务器中的特定预算项目互动。人们可以删除一个预算或切换其提醒状态。

import { FaTimes } from 'react-icons/fa'

/*This will enable one to set the reminder to the budget on or off when double clicked on; and also to delete the budget*/
const Budget = ({ budget, onDelete, onToggle }) => {
  return (
  <!-- Toggle the budget reminder on or off when double on double click -->
      <div
        className={`budget ${budget.reminder && 'reminder'}`}
        onDoubleClick={() => onToggle(budget.id)}
      >
        <h3>
          <!-- Display the budget name -->
          {budget.name}{' '}
            <FaTimes
            /*Delete the budget when clicked*/
            style={{ color: 'red', cursor: 'pointer' }}
              onClick={() => onDelete(budget.id)}
              />
          </h3>

            <!-- Display the budget Amount -->
            <p>{budget.amount}</p>
        </div>
  )
}

export default Budget

上面的代码。

  • 当双击时,充当提醒状态的切换器(开、关)。
  • 显示项目和金额。

AddBudget组件

AddBudget.js 文件允许人们向系统添加预算。然后,预算将立即在系统中被更新,并使其可见。

import { useState } from 'react'

const AddBudget = ({ onAdd }) => {
  const [name, setName] = useState('')
  const [amount, setAmount] = useState('')
  const [reminder, setReminder] = useState(false)

  const onSubmit = (e) => {
    e.preventDefault()

    /*Ensure that the name input is never null*/
    if (!name) {
      alert('Please add a budget')
      return
    }

    /*When adding the budget, store the name, amount and the reminder status*/
    onAdd({ name: name, amount: amount, reminder })

    setName('')
    setAmount('')
    setReminder(false)
  }

  /*Display a form that allows one to enter the budget values*/
  return (
  <form className='add-form' onSubmit={onSubmit}>
    <div className='form-control'>
      <label>Budget</label>
      <input
        type='text'
        placeholder='Add Budget'
        value={name}
        onChange={(e) => setName(e.target.value)}
        />
    </div>

    <!--  Take in the amount -->
    <div className='form-control'>
      <label>Amount</label>
      <input
              type='text'
              placeholder='Amount'
              value={amount}
              onChange={(e) => setAmount(e.target.value)}
      />
    </div>

    <!-- Take in the reminder status -->
    <div className='form-control form-control-check'>
      <label>Set Reminder</label>
      <input
              type='checkbox'
              checked={reminder}
              value={reminder}
              onChange={(e) => setReminder(e.currentTarget.checked)}
      />
    </div>

    <input type='submit' value='Save Budget' className='btn btn-block' />
  </form>
  )
}

export default AddBudget

上面的代码。

  • 在添加过程中,如果没有添加预算项目,会显示一个错误。
  • 否则,它会将输入的数值添加到数据源中的其他数值中。当提交按钮被按下时,添加就发生了。
  • 它允许人们为某一项目设置提醒onoff
  • 然后,应用程序将自动重新加载添加的列表。

Budgets.js文件

  • Budgets.js 文件中,我们可以添加以下代码。
import Budget from './Budget'

/*Displays all the budgets fetched from the URL to the screen*/
const Budgets = ({ budgets, onDelete, onToggle }) => {
/*Maps each budget per the budget's key*/
  return (
    <>
      {budgets.map((budget, index) => (
      <Budget key={index} budget={budget} onDelete={onDelete} onToggle={onToggle} />
      ))}
    </>
    )
}

export default Budgets

这段代码。

  • 显示预算列表中的项目。
  • 允许从列表中,以及从数据源中删除这些项目。
  • 它允许人们使用一个切换函数来设置提醒onoff

从服务器上获取项目

这一步是在App.js 文件中完成的。它规定了应用程序如何与服务器交互,以及如何处理获取的数据。

/*Import the other components for the application*/
import {useEffect, useState} from 'react'
import {BrowserRouter as Router, Route} from 'react-router-dom'
import Header from './components/Header'
import Footer from './components/Footer'
import Budgets from './components/Budgets'
import AddBudget from './components/AddBudget'
import About from './components/About'

const App = () => {
const [showAddBudget, setShowAddBudget] = useState(false)
const [budgets, setBudgets] = useState([])

useEffect(() => {
  /*Make the app fetch the items assynchronously*/
  const getBudgets = async () => {
    const budgetsFromServer = await fetchBudgets()
    setBudgets(budgetsFromServer)
  }

  getBudgets()
}, [])

该代码导入了所需的模块,并允许从服务器上异步获取数据项。

  • 在前面的代码下添加下面的代码。
// Fetch Budgets
const fetchBudgets = async () => {
  const res = await fetch('http://localhost:5000/budgets')
  const data = await res.json()

  return data
}

// Fetch Budgets
const fetchBudget = async (id) => {
  const res = await fetch(`http://localhost:5000/budgets/${id}`)
  const data = await res.json()

  return data
}

// Add Budget
const addBudget = async (budget) => {
  const res = await fetch('http://localhost:5000/budgets', {
  method: 'POST',
  headers: {
    'Content-type': 'application/json',
  },
  body: JSON.stringify(budget),
  })

  const data = await res.json()

  setBudgets([...budgets, data])
}

// Delete Budget
const deleteBudget = async (id) => {
  const res = await fetch(`http://localhost:5000/budgets/${id}`, {
    method: 'DELETE',
  })
  //We should control the response status to decide if we will change the state or not.
  res.status === 200
    ? setBudgets(budgets.filter((budget) => budget.id !== id))
    : alert('Error Deleting This Budget')
}

// Toggle Reminder
const toggleReminder = async (id) => {
const budgetToToggle = await fetchBudget(id)
const updateBudget = {...budgetToToggle, reminder: !budgetToToggle.reminder}

const res = await fetch(`http://localhost:5000/budgets/${id}`, {
  method: 'PUT',
  headers: {
    'Content-type': 'application/json',
  },
  body: JSON.stringify(updateBudget),
})

  const data = await res.json()

  setBudgets(
    budgets.map((budget) =>
            budget.id === id ? {...budget, reminder: data.reminder} : budget
    )
  )
}

该代码指定了其中的URL,可以。

  • 添加一个新的预算。

  • 删除一个预算。

  • 获取预算。

  • 切换提醒状态。

  • 现在添加一个返回和一个导出语句,如下所示。

/*Display all the budgets fetched, otherwise display that there are no budgets to show*/
return (
  <Router>
    <div className='container'>
      <Header
        onAdd={() => setShowAddBudget(!showAddBudget)}
        showAdd={showAddBudget}
      />
      <Route
        path='/'
        exact
        render={(props) => (
          <>
            {showAddBudget && <AddBudget onAdd={addBudget}/>}
            {budgets.length > 0 ? (
              <Budgets
                budgets={budgets}
                onDelete={deleteBudget}
                onToggle={toggleReminder}
              />
            ) : (
                'No Budgets To Show'
            )}
          </>
        )}
      />
      <Route path='/about' component={About}/>
      <Footer/>
    </div>
  </Router>
)
}

export default App

上面显示的这段代码做了以下工作。

  • 从指定的URL中获取项目并显示它们。
  • 将项目添加到列表中。
  • 删除数据源中的项目。
  • 切换项目提醒(开,关)状态。
  • 如果应用程序在服务器上没有找到数据,它将显示没有找到预算;否则,它将显示所有其他预算。
  • 该代码还包含页脚和关于页面的链接。

应用程序的风格

  • 现在我们可以为应用程序创建样式。样式代码可以在这个链接上找到。下载它并保存在src 文件夹中。

在使用下面的命令运行应用程序之前,请确保运行下面的命令来安装所有必要的软件包。

npm install

使用下面的命令运行创建的应用程序。

npm run start

该应用程序将如下图所示。

Home page

Add items

About page

安装json-server

JSON服务器可以通过运行下面的命令来安装。

npm install -g json-server

该命令在全局范围内安装该软件包。安装完毕后,前往package.json 文件,添加一个快速运行服务器的脚本。

"server": "json-server --watch db.json --port 5000"

上面这段代码运行一个服务器,为应用程序的请求提供响应。在这个应用程序中充当数据库的数据源是db.json 文件。如上图所示,它将通过端口5000 ,并在App.js 文件中被访问。

配置json-server数据源

db.json 文件中,服务器在http://localhost:5000/budgets/ URL下提供请求。数据项在预算部分下。

把下面的代码复制粘贴到db.json 文件中。

{
  "budgets": [
    {
      "id": 1,
      "name": "Carrots",
      "amount": "1500",
      "reminder": false
    },
    {
      "id": 2,
      "name": "Laundry",
      "amount": "2500",
      "reminder": true
    },
    {
      "id": 3,
      "name": "Ginger",
      "amount": "1000",
      "reminder": true
    },
    {
      "id": 4,
      "name": "Electricity",
      "amount": "10000",
      "reminder": true
    },
    {
      "name": "Water",
      "amount": "13000",
      "reminder": true,
      "id": 5
    }
  ]
}

它包含预算部分下的五个项目。这些是Carrots,Laundry,Ginger,Electricity, 和Water

运行应用程序

通过以下方式测试JSON服务器。

  • 在一个终端中通过使用运行主React应用程序。
npm run start
  • 在另一个终端中,使用运行服务器。
npm run server
  • 在浏览器中通过以下URL访问该应用程序。http://localhost:3000/.
  • 重新加载应用程序的浏览器窗口,直到它显示项目,如果它因任何原因不工作。

结果应该像下面的例子一样。

Final image for the application

关于JSON服务器的更多信息

让我们更多地了解这个包。

改变端口、文件和文件路径

通过在终端运行下面的命令,可以将服务器运行的文件名和端口改为database.json ,端口为3010

json-server --watch database.json --port 3010
  • 位于不同文件夹中的静态文件也可以提供服务,如下图所示。
json-server database.json --static ./public/database

对数据进行查询

在使用搜索栏进行搜索时,这一操作可能会有帮助。按照下面的步骤进行。

  • 通过在一个新的终端上运行以下内容来查询数据库中的一个特定值。
curl http://localhost:5000/budgets?q=Carrots

在这里,数据库中被搜索到任何一个数值为Carrots 的项目。返回值看起来像下面的例子。

Perform queries

该模块允许中间件、随机数据生成、远程访问数据源、设置自定义路由等。

添加延迟和改变主机

  • 要改变主机,使用-H--host 选项。
  • 给服务器添加一些延迟(以毫秒为单位),以复制一个真实的服务器,使用-d--delay 选项。

这两个选项都显示在下面。

json-server --watch db.json --port 5000 -H 127.0.0.1 -d 1500

结论

总之,在软件开发过程中,运行和丢弃的部分对开发者来说是必不可少的。这些部件对敏捷编程和原型设计很有帮助。JSON服务器依赖性是一个可快速丢弃的项目开发单元的例子。

它体积小,易于安装、使用、学习,并在人们使用完原型后进行处置。

在这一点上,已经涵盖了以下内容。

  • 什么是JSON服务器模块。
  • JSON服务器模块在项目开发阶段的重要性。
  • 将JSON服务器模块添加到React项目中。
  • 配置JSON服务器模块。