内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

小程序中Redux的使用

2018-09-14 11:15 出处:清屏网 人气: 评论(0

Android 程序员,关注大前端各种新兴技术。

在我们的一款小程序中聊天部分主要是基于 Redux 来维护数据部分的。为什么使用了 Redux ?这也是符合了使用 Redux 的一些原则的。那么哪些情况使用 Redux 比较好呢?

用户的使用方式复杂

不同身份的用户有不同的使用方式(比如普通用户和管理员)

多个用户之间可以协作

与服务器大量交互,或者使用了 WebSocket

View 要从多个来源获取数据

我们的聊天功能基于 WebSocket 交互数据,使用方式较为复杂,多个地方都会影响聊天呈现的数据内容。并且与服务器交互量比较大,UI 上呈现的内容受到多个地方的影响。如下图:

图中展示了 Redux 的三大块业务实现部分与业务部分的交互逻辑,其中数据会反应在首页和聊天界面,而首页及聊天界面的一些操作又会通过 Action 反馈到 Redux 的数据对象上。另外 Websocket 和 Http 网络部分也会有很多数据反馈到 Redux 的数据对象上。

Redux 设计思想

简单总结为两句话:

(1)Web 应用是一个状态机,视图与状态是一一对应的。

(2)所有的状态,保存在一个对象里面。

Redux 的三大原则

  1. 单一数据源

  2. State 是只读的

  3. 使用纯函数来执行修改

其工作逻辑如下图所示:

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

分享给小伙伴们:
本文标签: Redux小程序

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

CopyRight © 2015-2016 QingPingShan.com , All Rights Reserved.

清屏网 版权所有 豫ICP备15026204号