阿里前端开源 React框架 Mirror

赞赏 2017-08-22

Mirror一款简洁、高效、易上手的 React 框架, 由阿里巴巴 FGT 前端团队开发,目前在整个集团内部已有多个使用 React 技术栈的团队使用。下面我们看看为什么要搞React框架Mirror以及它解决了哪些问题?


我们热爱 React 和 Redux。

一个典型的 React/Redux 应用看起来像下面这样:

  • 一个 actions/ 目录用来手动创建所有的 action type(或者 action creator);
  • 一个 reducers/ 目录以及无数的 switch 来捕获所有的 action type
  • 必须要依赖 middleware 才能处理 异步 action
  • 明确调用 dispatch 方法来 dispatch 所有的 action;
  • 手动创建 history 对象关联路由组件,可能还需要与 store 同步;
  • 调用 history 上的方法或者 dispatch action 来手动更新路由;

存在的问题?太多的 样板文件 以及繁琐甚至 重复的劳动 

实际上,上述大部分操作都是可以简化的。

比如,在单个 API 中创建所有的 action 和 reducer;比如,简单地调用一个函数来 dispatch 所有的同步和异步 action,且不需要额外引入 middleware;再比如,使用路由的时候只需要关心定义具体的路由,不用去关心 history 对象,等等。

这正是 Mirror 的使命,用极少数的 API 封装所有繁琐甚至重复的工作,提供一种简洁高效的更高级抽象,同时保持原有的开发模式。


特性

  • 极简 API(只有 4 个新 API)
  • 易于上手
  • Redux action 从未如此简单
  • 支持动态创建 model
  • 强大的 hook 机制


举例:

一个典型的 React/Redux 应用看起来像下面这样:

actions.js

export const ADD_TODO = 'todos/add'
export const COMPLETE_TODO = 'todos/complete'
export function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}
export function completeTodo(id) {
  return {
    type: COMPLETE_TODO,
    id
  }
}

reducers.js

import { ADD_TODO, COMPLETE_TODO } from './actions'
let nextId = 0

export default function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      return [...state, {text: action.text, id: nextId++}]
    case COMPLETE_TODO:
      return state.map(todo => {
        if (todo.id === action.id) todo.completed = true
        return todo
      })
    default:
      return state
  }
}

Todos.js

import { addTodo, completeTodo } from './actions'// ...

// 在某个事件处理函数中
dispatch(addTodo('a new todo'))

// 在另一个事件处理函数中
dispatch(completeTodo(42))

看起来是不是有点繁冗?这还是没考虑 异步 action 的情况呢。如果要处理异步 action,还需要引入 middleware(比如 redux-thunk 或者 redux-saga),那么代码就更繁琐了。


使用 Mirror 重写

Todos.js

import mirror, { actions } from 'mirrorx'
let nextId = 0

mirror.model({
  name: 'todos',
  initialState: [],
  reducers: {
    add(state, text) {
      return [...state, {text, id: nextId++}]
    },
    complete(state, id) {
      return state.map(todo => {
        if (todo.id === id) todo.completed = true
        return todo
      })
    }
  }
})

// ...

// 在某个事件处理函数中
actions.todos.add('a new todo')

// 在另一个事件处理函数中
actions.todos.complete(42)

是不是就简单很多了?只需一个方法,即可定义所有的 action 和 reducer(以及 异步 action)。

而且,这行代码:

actions.todos.add('a new todo')

完全等同于这行代码:

dispatch({
  type: 'todos/add',
  text: 'a new todo'
})

完全不用关心具体的 action type,不用写大量的重复代码。简洁,高效


异步 action

上述代码示例仅仅针对同步 action

事实上,Mirror 对异步 action 的处理,也同样简单:

mirror.model({  // 省略前述代码
  effects: {
      async addAsync(data, getState) {
            const res = await Promise.resolve(data)
            // 调用 `actions` 上的方法 dispatch 一个同步 action
            actions.todos.add(res)
    }
  }
})

没错,这样就定义了一个异步 action。上述代码的效果等同于如下代码:

actions.todos.addSync = (data, getState) => {
  return dispatch({
    type: 'todos/addAsync',
    data
  })
}

调用 actions.todos.addSync 方法,则会 dispatch 一个 type 为 todos/addAsync 的 action。

你可能注意到了,处理这样的 action,必须要借助于 middleware。不过你完全不用担心,使用 Mirror 无须引入额外的 middleware,你只管定义 action/reducer,然后简单地调用一个函数就行了。


更多详见中文的readme:

https://github.com/mirrorjs/mirror/blob/master/README_zh.md

GIthub地址:

https://github.com/mirrorjs/mirror

登陆后阅读全文
阅读 2899 赞赏 0 有用 11 没用 0 收藏 1 分享

   



0 条留言

相关文章

Github 如何在命令行下处理 Pull Request?

Linux 安装 gcc 报错:[Errno 14] HTTP Error 404

如何使用 Issue 管理软件项目? (Github)

php composer install 慢 不动 怎么办?

黑客成长技术清单 (GitHub 万星推荐)

全文搜索引擎 ElasticSearch 入门教程

有料推荐

这世界欠我一个这样的老公!

高校学生模仿“世界名画”摆拍,可以说是戏精本精了

iPhone X 跌破发行价,苏宁200亿入股恒大 | 财经日日评

果然是高手!这次在日本,特朗普竹杠敲得不是一般狠

资深黄牛现身说法:iPhone X价格秒变不停,就像炒股一样

长一样的双胞胎也能识别?蚂蚁金服发布「眼纹识别」技术

苏联是怎么被阿富汗拖垮的?

美团或入局「分时租赁」共享汽车,王兴要大笔投入「泛出行」领域了? | 36氪独家

你或许被“一盘番茄炒蛋”刷屏了,但有人辛酸,有人质疑

iPhone X发售前夜,黄牛与苹果公司的不安

他的文章

阿里云·业务运营团队内部的前端构建和工程化工具 Dawn开源

npm安装更新慢、网络异常等等 淘宝的cnpm来帮你

阿里前端开源 React框架 Mirror

手机扫一扫
分享文章