前言
长久以来,在开发移动端应用(包括 Web 应用,以下简称「应用」)时,我们习惯性地将「离线」当作一种错误来对待。作为应用的创建者,我们在越来越稳定和快速的办公网络下设计和开发着这些应用,渐渐地对那些做不到时刻在线的用户们失掉了同理心。实际上这些「掉了线」的用户离我们并不远,他们也许是通勤路上不得不挤进没有信号的地铁中的上班族,也许是喜欢拿着手机跑进 Wi-Fi 鞭长莫及的厕所蹲马桶的游戏玩家。他们在我们身边,他们就是我们。来自 《Redis 入门指南》作者 李子骅 luin
拥抱离线优先
公司的产品的因为地区,在某种情况下,无法连接网络。必须使用APP的某功能,保证一线业务人员的工作能正常运行。提供离线的功能,对我司的产品来说意义重大。 为了满足这些复杂而又琐碎的离线需求。我们最终确定了 离线优先 的开发模式。
离线不是一种错误,在线则是一种特性
离线优先指的是开发应用时以离线为目标场景,同时针对联网的情况增加额外的功能。就我司的产品而言,我们会预设用户始终处于没有网络连接的状态,并让用户能够在这个状态下可以正常地使用大部分功能。同时,当联网后,我们额外为用户提供离线同步等功能。
数据先修改后同步
无论是否在线,我们都默认用户处于离线的状态。用户对数据的所有修改都是直接写入到本地数据中(即使当前是联网状态)并实时得到反馈,应用会在后台通过独立的组件定时将这些修改和服务器进行同步。 所以,我们应该同一个地方进行数据的保存和维护。所以,我们在决定引入react-redux。
每个对应的模块,都封住单独封装一个 reducer 和 action,并引入 redux-logger 插件,方便检测和调试数据的变化
Redux Offline
对于项目使用了 redux 数据管理的项目而言,最快捷的办法,就是使用 redux-offline,其基本思路是通过 redux middleware 监听每次 acton 数据变化,然后将需要离线的数据序列化到本地,等下一次刷新页面时,优先从本地还原数据还原到 store 中。这种方案的好处是快速配置需要缓存的 API 接口到中间件即可,充分结合了 redux 特性,对于想要达到简单优先展示离线数据的应用而言,是非常不错的。
统一数据格式, normalizr
所有数据都存储Redux的Store,那么我们不能随随便便的把离线需要更新的数据进行粗暴的存储到Store里面,从API,获取数据的时候的 通过 normalizr 进行统一个规范序列化,酱紫大大方便了,可以很清晰地了解数据的结构了。
未 normalizr
{
"id": "123",
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
}
import { normalize, schema } from 'normalizr';
// Define a users schema
const user = new schema.Entity('users');
// Define your comments schema
const comment = new schema.Entity('comments', {
commenter: user
});
// Define your article
const article = new schema.Entity('articles', {
author: user,
comments: [comment]
});
const normalizedData = normalize(originalData, article);
normalizr 后
{
result: "123",
entities: {
"articles": {
"123": {
id: "123",
author: "1",
title: "My awesome blog post",
comments: [ "324" ]
}
},
"users": {
"1": { "id": "1", "name": "Paul" },
"2": { "id": "2", "name": "Nicole" }
},
"comments": {
"324": { id: "324", "commenter": "2" }
}
}
}
获取清晰结构化,如何进行保存到本地和如何更新到视图,和发送数据给后端更新,简直易如反掌了。
结语
......