内容简介:作者 | 张鹏Android 程序员,关注大前端各种新兴技术。
作者 | 张鹏
Android 程序员,关注大前端各种新兴技术。
在我们的一款小程序中聊天部分主要是基于 Redux 来维护数据部分的。为什么使用了 Redux ?这也是符合了使用 Redux 的一些原则的。那么哪些情况使用 Redux 比较好呢?
用户的使用方式复杂
不同身份的用户有不同的使用方式(比如普通用户和管理员)
多个用户之间可以协作
与服务器大量交互,或者使用了 WebSocket
View 要从多个来源获取数据
我们的聊天功能基于 WebSocket 交互数据,使用方式较为复杂,多个地方都会影响聊天呈现的数据内容。并且与服务器交互量比较大,UI 上呈现的内容受到多个地方的影响。如下图:
图中展示了 Redux 的三大块业务实现部分与业务部分的交互逻辑,其中数据会反应在首页和聊天界面,而首页及聊天界面的一些操作又会通过 Action 反馈到 Redux 的数据对象上。另外 Websocket 和 Http 网络部分也会有很多数据反馈到 Redux 的数据对象上。
Redux 设计思想
简单总结为两句话:
(1)Web 应用是一个状态机,视图与状态是一一对应的。
(2)所有的状态,保存在一个对象里面。
Redux 的三大原则
-
单一数据源
-
State 是只读的
-
使用纯函数来执行修改
其工作逻辑如下图所示:
Store
Store 就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个 Store。
import { createStore } from 'redux'; const store = createStore(fn);
通过 Store 可以获取到 State 对象,State 为时点的数据集合,即 Store 的一个快照。
import { createStore } from 'redux'; const store = createStore(fn); const state = store.getState();
Action
State 的变化,会导致 View 的变化。但是,用户接触不到 State,只能接触到 View。所以,State 的变化必须是 View 导致的。Action 就是 View 发出的通知,表示 State 应该要发生变化了。
const action = { type: 'ADD_TODO', payload: 'Learn Redux' };
Dispatch
store.dispatch()
是 View 发出 Action 的唯一方法。
import { createStore } from 'redux';const store = createStore ( fn ); store . dispatch ({ type : 'ADD_TODO' , payload :
'Learn Redux'
});Subscribe
Store 允许使用 store.subscribe
方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。
import { createStore } from 'redux'; const store = createStore(reducer); store.subscribe(listener);
小程序
在 Redux 的使用中我们主要会去实现两个部分,一是 Action 部分,去构造定义要发送的 Action 的数据格式等,另一部分是 Reducer 部分,即 Dispatch 分发的 Action 的具体相应处理部分。Reducer 即接收原 State 和 Action,根据当前 Action 重新创建一份新的 State,然后返回这个 State。
消息的处理逻辑一开始并不是很好,发送消息、接收消息、发送中、接收中等各种消息的状态,都会单独发送不同的 Action 这也导致 Reducer 的维护变得非常困难,而且导致很多不一致的地方。
后来改为一个 Action 做统一处理,处理起来简单了很多,将原有的多种 Action,多种接收 Action 并处理的逻辑统一成一种,当然如果是维护的不同数据那么还是需要分开来处理的。
修改后 Action 的实现
修改后消息 Action 接口如下:
onMessage(message, doctorId)
如两处修改消息 Action 的使用:
-
接收消息,WebSocket 接收到新的消息时,因为接收到的消息分为发送出去的,和接收到的两种:
onMessage({ ...message, sending: { status: 0 }}, message.from === config.patientId ? message.to : message.from );
-
发送消息,本地发送消息时,将其更新到界面上,并调用WebSocket发送接口将其发送出去。
const sendText = async (doctorId, text) => { const message = { typ: MSG.TEXT, content: toRealText(text), to: doctorId, mine: true, sending: { status: 1 }, guid: guid(), from: config.patientId, created: Date.now() } onMessage(message, doctorId) }
修改后 Reducer 的实现
在 Reducer 统一提供一处消息 Action 的处理方式,避免之前的多处处理导致的数据不一致的情况:
[CHAT_MESSAGE] (_state, _action) { // 拷贝一份 state let state = {..._state}; // 提取消息参数 _handle(_state, _action); // 处理消息对象 // 修改 state // ... return state; }
修改后 UI 订阅状态
最后我们需要将 State 中维护的数据对象显示到 UI 上,在 Javascript 中我们可以使用 @connect 在页面上加上修饰,通过 @connect 实现内容的 subscribe
过程,将 messages 方法注入到页面中的 data 中。
@connect({ messages(state) { const chat = state.chat[this.doctorId]; if (chat) { return chat.messages; } return []; } })
对于首页也是同样的道理,在首页不需要消息列表,但是需要小时列表的摘要信息以显示有多少种消息列表。也即当前维护着的对话数量。
@connect({ sessions(state) { let sessions = [] for (let id in state.chat) { let session = state.chat[id] sessions.push(session.session) } sessions.sort((a, b) => { return b.updated - a.updated }) return sessions } });
总结
小程序里使用到的内容较为简单,Redux 原本也就是简化 Web 中状态和界面简单对应关系,使用时只需要关注其三大原则即可。并尽可能地统一相同的修改操作,保持数据的统一性。
参考
http://www.redux.org.cn/ http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html
全文完
以下文章您可能也会感兴趣:
我们正在招聘 Java 工程师,欢迎有兴趣的同学投递简历到 rd-hr@xingren.com 。
杏仁技术站
长按左侧二维码关注我们,这里有一群热血青年期待着与您相会。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 不会使用虚拟机的程序员不是好程序员
- dotnet core 使用 CoreRT 将程序编译为 Native 程序
- 在iOS应用程序中登录系统使用的标准程序是什么?
- 使用Taro框架开发小程序
- 小程序使用 async await
- 小程序系列--如何使用分包加载
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。