前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >9. redux如何精简代码

9. redux如何精简代码

作者头像
MasterVin
发布2018-08-30 10:13:39
1.1K0
发布2018-08-30 10:13:39
举报
文章被收录于专栏:文大师的新世界

经过2天折腾,终于把API全面切换到GitHub,总结一下经验:

  • redux精简代码
  • 使用redux-persist持久化数据
redux如何减少样板代码#####

通过之前的代码不难看出redux系统里的ActionTypeActionReducer都有一定的共性,小项目无所谓,这样写更清晰,但是一旦组件以及业务增多,开发效率就不是很高了。本来是打算使用第三方组件的,比如redux-actions(https://github.com/acdlite/redux-actions)等,但是实验了一下,功力不足反而没有成功,然后自己照抄官方说明写了一下,发现代码出乎意料的简单,核心代码直接照抄的官方文档,看官嫌我啰嗦可以直接跳过本文去原文档,中文英文。下面就我自己的理解在此记录一下。 通过改造,下面是一个请求GitHub Search Repositories APIaction的最终代码:

代码语言:javascript
复制
export function searchRepos(q = 'react-native', page = 1, per_page = 15) {
    return {
        // Types of actions to emit before and after
        types: [SEARCH_REPOS_REQUEST, SEARCH_REPOS_SUCCESS, SEARCH_REPOS_FAILURE],
        // Perform the fetching:
        callAPI: () => Util.get(Api.search_repos, {
            q,
            page,
            per_page,
        }),
        // Arguments to inject in begin/end actions
        payload: {
            q,
            page,
            per_page,
        }
    }
}

API 请看 GitHub V3GET /search/repositories

因为每个fetch api的过程都是requestsuccessfailurereduxaction返回的对象必须是这样的{type: ...},那么这样的action如何解析呢,这就要使用中间件了,前文说了,redux里都是函数式的,这就可以让我们在传递过程中做处理了,其实可以理解为类似java spring中的AOPservlet中的拦截器,nodejs express中的koa,具体代码照文档,几乎一字未改: app/callAPIMiddleware.js

代码语言:javascript
复制
export default function callAPIMiddleware({ dispatch }) {
  return next => action => {
    const {
      types,
      callAPI,
      payload = {}
    } = action

    if (!types) {
      // Normal action: pass it on
      return next(action)
    }

    if (
      !Array.isArray(types) ||
      types.length !== 3 ||
      !types.every(type => typeof type === 'string')
    ) {
      throw new Error('Expected an array of three string types.')
    }

    if (typeof callAPI !== 'function') {
      throw new Error('Expected callAPI to be a function.')
    }

    const [ requestType, successType, failureType ] = types

    dispatch(Object.assign({}, payload, {
      type: requestType
    }))

    return callAPI().then(
      response => dispatch(Object.assign({}, payload, {
        response,
        type: successType
      })),
      error => dispatch(Object.assign({}, payload, {
        error,
        type: failureType
      }))
    )
  }
}

可以看到最后的return和以前的action是一模一样的。 在创建store的时候链接我们自己的中间件,修改app/store.js如下

代码语言:javascript
复制
applyMiddleware(thunk, logger, callAPIMiddleware)

最后reducer我没有更改,标准FLUX流程是需要改的,套用文档中一句话解释原因:

switch 语句 不是 真正的模版。真正的 Flux 模版是概念性的:发送更新的需求,用 Dispatcher 注册 Store 的需求,Store 是对象的需求 (当你想要一个哪都能跑的 App 的时候复杂度会提升)。不幸的是很多人仍然靠文档里用没用 switch 来选择 Flux 框架。

这里是因为我以前的代码不够规范,在reducer里处理了分页数据,无论是本着单一职责或是其他的设计原则来讲,这都是不好的,在此特别提出请勿模仿。 在组件内部调用的的方式没有任何改变,这也是redux的强大之处。 给个效果图

search react-native

持久化数据#####

手机端肯定需要考虑离线的情况发生,有了redux,这件事情就简单了,只需要把store这个state树持久化就OK了,官方持久化接口使用的是AsyncStorage,这里为了简化操作,使用第三方组件redux-persist项目地址,代码很简单,修改app/store.js如下:

代码语言:javascript
复制
import {autoRehydrate, persistStore} from 'redux-persist';
...
function configureStore(onComplete: ? () => void) {
     const store = autoRehydrate()(createStoreWithMiddleware)(appReducers);
     persistStore(store, {
         storage: AsyncStorage
     }, onComplete);
     if (isDebugInChrome) {
         window.store = store
     }
     return store;
 }

README文档很详细,就不赘述了,完整代码地址

首页

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016.08.24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • redux如何减少样板代码#####
  • 持久化数据#####
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档