前言:Rematch和vuex很像。

文档:https://github.com/yurizhang/rematch

简介:

先看看rematch的官方介绍:

Rematch是没有boilerplate的Redux最佳实践。没有多余的action types,action creators,switch 语句或者thunks。

rematch是在redux的基础上再次封装后成果,在rematch中我们不用声明action类型、action创建函数、thuks、store配置、mapDispatchToProps、saga。如果你习惯使用vuex,那么你一定会喜欢上rematch的,因为rematch的写法和vuex基本一样。

一个简单的demo:

先看看我们的项目结构:

├── index.html
├── index.js        # 项目的入口
├── ....
└── store
├── index.js # 引入modules的各个模块,初始化store的地方
└── modules
├── count.js # count模块
└── info.js    # info模块

1. store/index.js,初始化一个store实例

 
import { init } from '@rematch/core';
import count from './modules/count';
import info from './modules/info'; const store = init({
models: {
count,
info,
}
}) export default store;
 

   rematch提供 init()方法,返回一个store的实例。初始化store的时候rematch支持传入多个模块,在中、大型项目中可以根据业务的需要,拆分成多个模块,这样项目的结果就会变得清晰明了。

2. store/modules/count.js,编写count模块业务代码

const count = {
state: {
num: 1,
     type: 2
},
reducers: {
increment(state, num1, num2) { // 从第二个变量开始为调用increment时传递进来的参数,后面依次类推,例如:dispatch.count.increment(10, 20)时, num1 = 10 , num2 = 20.
return {
          ...state,
num: num1
}
},
},
effects: {
async incrementAsync(num1, rootState, num2) { // 第二个变量为当前model的state的值,num1为调用incrementAsync时传递进来的第一个参数,num2为调用时传递的第二个参数,后面依次类推。例如:dispatch.count.incrementAsync(10, 20)时,num1 = 10, num2 = 20
await new Promise(resolve => setTimeout(resolve, 2000));
this.increment(num1);
}
}
} export default count;
 

  事实上我们的count模块就是一个对象,该对象包含三个属性:state、reducers、effects。

  state:存放模块状态的地方。

  reducers:改变store状态的地方,每个reducers函数都会返回一个对象作为模块最新的state。reducers中的函数必须为同步函数,如果要异步处理数据需要在effects中处理。注意:只能通过在reducers的函数中通过返回一个新的对象来改变模块中state的值,直接通过修改state的方式是是不能改变模块的state的值。例:

        increment(state, num1) {
state.num = num1 // 这样的写法是错误的
},

  effects:处理异步数据的地方,比如:异步从服务端获取数据。注意:在effects中是不能修改模块的state,需要在异步处理完数据后调用reducers中的函数修改模块的state。

  rematch的state、reducers、effects和vuex的state、mutaition、action用法非常相似,在vuex中mutation修改model的state的值,action进行异步处理数据。

 3. 在组件中获取state和修改state的值

  有2种方法可以获取state和修改state:(1)使用redux的高阶组件connect将state、reducers、effects绑定到组件的props上。(2)使用rematch提供的dispatch和getState。

  (1)使用redux的高阶组件connect

    使用redux提供的高阶组件connect给App组件注册countState和countDispatch属性,其中countState对应的是count模块的state属性,countDispatch对应的是count模块的reducers和effects。在组件中使用this.props.countState和this.props.countDispatch就可以访问到count模块提供的state和reducers、effects了。

 
import React, {Component} from 'react';
import {connect} from 'react-redux'; class App extends Component {
handleClick = () => {
const { countDispatch } = this.props;
countDispatch.increment(10)
}; render() {
const { countState } = this.props;
return (
<div className="App" onClick={this.handleClick}>
当前num为{countState.num},点我num加10
</div>
);
};
} const mapStateToProps = (state) => ({
countState: state.count
}) const mapDispatchToProps = (dispatch) => ({
countDispatch: dispatch.count
}) export default connect(mapStateToProps, mapDispatchToProps)(App);
 

  (2)dispatch和getState

    getState:rematch提供的getState方法返回整个store的state对象,如果要单独访问count模块的state,只需要 getState( ).count即可。

    dispatch:rematch提供的dispatch可以直接调用整个store中定义的reducers和effects。例:dispatch.count.increment(10) ,其中count为store中的一个model,increment方法为count模块中提供的一个reducers。调用effects的方法和调用reducers的方法一样。

 
import React, {Component} from 'react';
import { dispatch, getState } from '@rematch/core'; class App extends Component {
handleClick = () => {
     console.log(getState().count); // {num: 1, a: 1}
dispatch.count.increment(10)
}; render() {
let countState = getState().count;
console.log(countState);
return (
<div className="App" onClick={this.handleClick}>
当前num为{countState.num},点我num加10
</div>
);
};
}
const mapStateToProps = (state) => ({
countState: state.count
}) const mapDispatchToProps = (dispatch) => ({
countDispatch: dispatch.count
}) export default connect(mapStateToProps, mapDispatchToProps)(App);
 

    

4、在一个model的reducers中的函数中触发另外一个model的reducers中的函数  

  场景:A函数和B函数里面有大量相似的代码,这个时候我们一般的做法都是将A、B函数的公共部分提取出来成一个公共函数,这样我们就不需要在A函数和B函数中写大量相似的代码。假如在reducers中,我们将A函数和B函数提取的公共函数C放在公共模块info的reducers中,A函数是在count模块的reducers中。在这种情况下我们就需要在公共模块info的函数C执行完后调用count模块的A函数。

 
{  // count模块
...
reducers: {
...
'info/addAge': (state, payload) => { // payLoad的值为addAge传入的值10
console.log(payload) // 10
return {
...state,
num: 10
}
}
},
...
} { // info模块
...
reducers: {
addAge(state, num) {
return {
age: state.age + num.age,
}
}
}
...
}
 

  通过dispatch.info.addAge(10)调用info模块的addAge函数,当addAge函数执行完后会触发count模块的 ' info/addAge ' ,并且 ' info/addAge '的参数payload的值为调用info模块的addAge函数时传入的参数 10

总结:

由于rematch的写法和vuex很相似,所以在接触rematch的时候觉得非常熟悉,很好上手.

Rematch Redux的替代品的更多相关文章

  1. react native redux 草稿

    Provider > Provider > 使组件层级中的 方法都能够获得 Redux store.正常情况下,你的根组件应该嵌套在 Provider 中才能使用 方法. 如果你真的不想把 ...

  2. 十分钟介绍mobx与react

    原文地址:https://mobxjs.github.io/mobx/getting-started.html 写在前面:本人英语水平有限,主要是写给自己看的,若有哪位同学看到了有问题的地方,请为我指 ...

  3. rematch:当你受不了redux繁琐写法的时候,是时候了解一波rematch了

    前言: 前段时间学习完react后,刚好就接到公司一个react项目的迭代,顺便巩固一下前段时间的学习成果.项目使用的是redux+react-router,将所有的数据都放在redux中,异步处理数 ...

  4. Redux counterpart rematch dva

    rematch https://github.com/rematch/rematch#examples 数据模型一个文件定义, 不用分散到 action actiontype reducer 文件 e ...

  5. Hydux: 一个 Elm-like 的 全功能的 Redux 替代品

    在学习和使用 Fable + Elmish 一段时间之后,对 Elm 架构有了更具体的了解, 和预料中的一样,Redux 这种来自 Elm 的风格果然还是和强类型的 Meta Language 语言更 ...

  6. 新手级配置 react react-router4.0 redux fetch sass

    前言 最近公司来了几个实习生,刚好我手头没什么要紧事,然后领导让我带他们学习react, 为下一个react项目做基础. 然后随手写了几个demo,帮助他们了解正经项目如何去构建配置项目. 现在分享出 ...

  7. rematch的基本用法

    rematch是对redux的二次封装,简化了redux是使用,极大的提高了开发体验.rematch仅仅是对redux的封装,没有依赖redux-saga,也没有关联react,因此其可以用在其他的视 ...

  8. RxJS + Redux + React = Amazing!(译一)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: https:/ ...

  9. 通过一个demo了解Redux

    TodoList小demo 效果展示 项目地址 (单向)数据流 数据流是我们的行为与响应的抽象:使用数据流能帮我们明确了行为对应的响应,这和react的状态可预测的思想是不谋而合的. 常见的数据流框架 ...

随机推荐

  1. J2EE 工作中注意事项

    [转载于http://www.cnblogs.com/hemingwang0902/archive/2012/01/06/2314215.html] 根据当前项目中代码存在的一些问题,编写了一个编码注 ...

  2. C/C++中变量类型最值之宏定义

    C/C++ [climits(limits.h)] CHAR_BIT        Number of bits for a char object (byte)                    ...

  3. Mysql 增量备份和全量备份

    全量备份: # vim /root/DBFullyBak.sh //添加以下内容 #!/bin/bash # Program # use mysqldump to Fully backup mysql ...

  4. 在VM12中安装ubuntu系统下的VMTOOLS

    转载自http://www.jb51.net/article/97387.htm 一.下载Ubuntu镜像: Ubuntu官网下载地址 二.创建虚拟机 打开VMware Workstation,点击创 ...

  5. jeecms 评论相关

    html WEB-INF-t-cms-www-gyxrmyy-content news.html 内容详情页 inc_comment_input.html 评论输入框 inc_comment_list ...

  6. 【TMF eTOM】业务流程框架介绍

    TMF文档版权信息 Copyright © TeleManagement Forum 2013. All Rights Reserved. This document and translations ...

  7. Zookeeper安装和部署

    Zookeeper安装和部署:ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用 ...

  8. JavaScript -- 数据存储

    Cookie Web应用程序是使用HTTP协议传输数据的.HTTP协议是无状态的协议. 一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接.这就意味着服务器无法从连接上跟踪 ...

  9. 反射实现增删改查(DAO层)——查询数据

    先贴出代码,后续补充自己的思路.配置文件.使用方式: /** * * 数据查询 * */ @Override public List<?> queryObject(List<Map& ...

  10. nodejs + webpack4 + babel6 结合写Chrome浏览器插件记录

    最近任务不忙,有时间了看一下Chrome插件相关的东西,于是想用nodejs + webpack写一个能直出插件的小工具. 1.nodejs + babel6 + webpack4 在写之前,是有把它 ...