使用 Redux 秒做 Nodejs todo-list 应用
使用 Redux 秒做 Nodejs todo-list 应用
原文: https://log.zvz.im/2016/10/13/build-todo-app/
React 采用组件和单向数据流的方式完美地解决了用户界面的构建问题,不过它所用于处理状态的工具设计得太简单了,感觉就是故意的;也可能是为了强调 React 只是对应传统的 MVC 架构中 View 的部分。
作者认为
没有什么能够阻止我们用 React 来构建越来越大的应用,但是很快我们就会发现,想要保持代码简单,我们到处都需要进行状态的管理。
尽管没有官方的解决方案,但是仍然有不少代码库依照 React 的设计理念解决了状态管理的问题。今天我们就要介绍两个这样的类库,并使用它们构建一个简单的小应用。
Redux
Redux 是一个极精简的库,它融合了 Flux 和 Elm 的设计理念,为应用状态提供容器功能。我们可以使用 Redux 管理任何应用的状态,使我们遵守以下准则:
- 状态( status )都保存在同一个存储( store )中;
- 动作( action )才能改变状态,状态不能直接被修改;
Redux 存储的核心是一个函数,它将当前应用的状态和动作结合起来,创建应用的新状态。我们将这个函数称为 reducer。
我们的 React 组件负责向我们的存储发送动作,相应地存储通知组件何时需要重绘。
ImmutableJS
由于 Redux 不允许直接对应用的状态做修改,所以使用不可修改数据作为应用状态,可以禁止对状态的修改,就显得非常好用了。
ImmutableJS 为我们提供了许多的不可修改的数据结构,以及对应的修改操作接口,其实现方式参考了 Clojure 和 Scala 中的现实,有很高的代码效率。
示例
接下来,我们将使用 React 、 Redux 和 ImmutableJS 来创建一个简单的待办事项列表,它允许我们添加待办事项,且能够切换事项完成状态。
你可以去 CodePen 看 SitePoint ([@SitePoint](/user/SitePoint) )实现的一个 React, Redux & Immutable Todo 应用。
也可以去 GitHub 上下载相应的代码。
准备工作
我们从建立项目文件目录开始,然后使用 npm init
指令初始化一个 package.json
文件。然 后我们开始安装我们需要的依赖库。
npm install --save react react-dom redux react-redux immutable
npm install --save-dev webpack babel-loader babel-preset-es2015 babel-preset-react
我们使用 JSX 和 ES2015 的语法,所以我们会在 Webpack 进行模块绑定时,用 Babel 来编译 我们的代码。
首先,我们新建一个 Webpack 的配置文件 webpack.config.js
。
module.exports = {
entry: './src/app.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query: { presets: [ 'es2015', 'react' ]}
}
]
}
};
然后我们需要扩充一下我们的 package.json
文件,加入一行 npm 脚本用来编译我们的代码。
"script": {
"build": "webpack --debug"
}
当我们需要编译代码时,只要执行一次 npm run build
命令即可。
这年头 todo-list 比 todo 都多
todo-list 都快成标准的前框架 benchmark 了
这种 example 一抓一大把
蛤蛤非常同意
git clone 再 npm i 一下就完成了,所以叫做秒做…… todo-list 成了前端标配了……
在 Node.js 环境中直接运行 Redux 并不常见,因为 Redux 主要用于前端状态管理。不过,你可以使用 Redux 的概念来设计一个类似 todo-list 的后端应用,虽然通常我们会用数据库(如 MongoDB)来存储任务列表。不过,为了简化,这里我将展示一个使用内存存储的 Node.js 应用,模拟 Redux 的状态管理。
首先,你需要安装 express
来创建服务器:
npm install express
然后,你可以创建一个简单的服务器来管理 todo-list:
const express = require('express');
const app = express();
const port = 3000;
let todos = [];
app.use(express.json());
app.post('/todos', (req, res) => {
const todo = req.body;
todos.push(todo);
res.status(201).send(todo);
});
app.get('/todos', (req, res) => {
res.send(todos);
});
app.delete('/todos/:id', (req, res) => {
const id = parseInt(req.params.id, 10);
todos = todos.filter(todo => todo.id !== id);
res.status(204).send();
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
这段代码创建了一个简单的 REST API,允许你添加、获取和删除 todo 事项。注意,这里使用内存存储,因此重启服务器会丢失所有数据。为了在生产环境中使用,请考虑使用数据库来持久化数据。