React RebixReact 的單向數(shù)據(jù)流框架
React的一個(gè)單向數(shù)據(jù)流框架。
優(yōu)點(diǎn)
內(nèi)部實(shí)現(xiàn)依賴于Redux。但是簡(jiǎn)化了Redux的使用方法。
-
action層只需要返回action方法的處理結(jié)果,無(wú)需action去dispatch處理的結(jié)果。
-
store層,無(wú)需寫(xiě)大量的switch判斷,而是采用reflux的風(fēng)格,直接使用onXXXX來(lái)響應(yīng)Action的處理。
-
view層無(wú)需自己去依賴action和store層,而是直接采用簡(jiǎn)單的配置,就能自動(dòng)將action和store中的數(shù)據(jù)綁定到組件的props中。
-
view層中調(diào)用的action方法如果是異步方法會(huì)將返回值中的promise對(duì)象透?jìng)鞯絭iew層。
-
action層和view層,都可以直接訪問(wèn)store中的Get方法。但是view層和action層,都無(wú)法訪問(wèn)store中的非get方法。這樣既能保證調(diào)用的靈活性,又能保證數(shù)據(jù)流的單向流動(dòng)。
-
跟其他框架相比,用戶省去了大量自己手動(dòng)書(shū)寫(xiě)的對(duì)數(shù)據(jù)的pub/sub的代碼。
安裝
npm install --save react-rebix
使用
import Rebix from 'react-rebix';
OR
<script src="/node_modules/react/dist/react.min.js"></script> <script src="/node_modules/react-dom/dist/react-dom.js"></script> <script src="/node_modules/react-rebix/dist/react-rebix.min.js"></script>
示例
TodoMVC
https://github.com/ubibi/rebix-todo-demo
https://github.com/luanhaipeng/rebix/tree/master/example/example
Action
Action中可訪問(wèn)Store中的getXXX方法,其他方法不能訪問(wèn)。
支持三種Action
-
異步 Action, 一定要返回一個(gè)Promise對(duì)象
-
普通 Action,直接返回處理結(jié)果的js對(duì)象。
-
空Action, 不需要具體的實(shí)現(xiàn),具體操作在Store中完成.
import Rebix from 'react-rebix';
import UserStore from '../stores/UserStore';
export default Rebix.createActions({
/**
* 異步 Action
* 一定要返回一個(gè)Promise對(duì)象
*/
getUserInfo: function (params) {
//Action 中可以訪問(wèn)Store中的數(shù)據(jù)。但是只能調(diào)用get方法。
//Store 中的其他方法,不會(huì)對(duì)外暴露,這樣方便了數(shù)據(jù)的訪問(wèn),同時(shí)又保證了數(shù)據(jù)的單向流動(dòng)。
var userInfo = UserStore.getUserInfo(123);
return new Promise(function (resolve) {
setTimeout(function () {
//store層使用action.promise字段接受返回值
resolve({
time: new Date().getTime(),
userInfo: userInfo,
params: params
});
}, 1000)
})
},
/**
* 普通 Action
*/
getUserList: function (params) {
//store層使用action.payload字段接受返回值
return [1, 2, 3, params];
},
/**
* 空Action, 不需要具體的實(shí)現(xiàn)
* 具體操作在Store中完成.
*/
beginEditUserInfo: null,
/**
* 空Action, 不需要具體的實(shí)現(xiàn)
* 具體操作在Store中完成.
*/
endEditUserInfo: null
});
Store
Store中的數(shù)據(jù)存儲(chǔ),強(qiáng)烈建議使用immutable,這里為了演示方便,通過(guò)Object.assign({}, state)創(chuàng)建了一個(gè)新對(duì)象。
說(shuō)明:
-
為了保證數(shù)據(jù)的單向流動(dòng),通過(guò)CreateStore創(chuàng)建的onXXXX函數(shù),view層和action層根本調(diào)用不到。
-
為了方便action和view層使用數(shù)據(jù),通過(guò)CreateStore創(chuàng)建的getXXXX函數(shù),view層和action層都可以調(diào)用到。
-
一般來(lái)說(shuō)action文件和store文件是一一對(duì)應(yīng)的,但是有時(shí)候一個(gè)action的處理結(jié)果需要幾個(gè)store層各自處理。這里提供了加井號(hào)前綴的方式實(shí)現(xiàn)。比如:post#onGetPostList(在UserStore中響應(yīng)PostAction的結(jié)果。)
import Rebix from 'react-rebix';
export default Rebix.createStore({
initialState: {
userList: [],
postList: []
},
//類(lèi)似Reflux。Action中的處理結(jié)束后,會(huì)把數(shù)據(jù)傳遞給Store
//這里處理:action中方法 getUserList 的返回值。
'onGetUserList': function (state, action) {
console.log(action.status);
state = Object.assign({}, state);
var userList = action.payload;
state.userList = userList;
return state;
},
//處理action中beginEditUserInfo的行為。
'onBeginEditUserInfo': function (state) {
state = Object.assign({}, state);
state.isEditing = true;
return state;
},
//處理action中onEndEditUserInfo的行為。
'onEndEditUserInfo': function (state) {
state = Object.assign({}, state);
state.isEditing = false;
return state;
},
/**
* 為了響應(yīng)其它Action方法中的處理,要加#前綴
*/
'post#onGetPostList': function (state, action) {
console.log(action.status);
if (action.status === 'success') {
state = Object.assign({}, state);
var postList = action.payload;
state.postList = postList;
}
return state;
},
/**
* Get函數(shù),修改state不管用.state內(nèi)部一般都是使用immutable對(duì)象,只有on函數(shù)的返回值才能對(duì)state進(jìn)行修改.
* View 層,可以直接調(diào)用Get函數(shù)獲取Store中的數(shù)據(jù),但是無(wú)法修改.
* 在Get函數(shù)內(nèi)部對(duì)state的任何修改,都不會(huì)生效.
*/
'getUserInfo': function (state, a, b, c, d) {
return {
name: a
};
}
});
Config
通過(guò)Config,將action、store等資源集中起來(lái)。這樣的目的是為了在view層,無(wú)需再引入大量的action、store的js文件。
說(shuō)明:
-
createConfigure中只有三個(gè)配置項(xiàng)。
-
initialState 是用來(lái)做服務(wù)端初次數(shù)據(jù)渲染用的。
-
actions 所有action的集合。
-
stores所有stores的結(jié)合。
-
actions和stores中配置的key值基本保證是一一對(duì)應(yīng)的。如下:user和post
import Rebix from 'react-rebix';
import UserActions from '../actions/UserActions';
import PostActions from '../actions/PostActions';
import UserStore from '../stores/UserStore';
import PostStore from '../stores/PostStore';
export default Rebix.createConfigure({
initialState: null,
actions: {
user: UserActions,
post: PostActions
},
stores: {
user: UserStore,
post: PostStore
}
});
View
注意:
-
Action中可訪問(wèn)Store中的getXXX方法,其他方法不能訪問(wèn)。
-
View層通過(guò)Rebix.createComponent將action和store自動(dòng)綁定到組建的props中。
-
Store發(fā)生了變化,會(huì)自動(dòng)update,因此強(qiáng)烈建議重寫(xiě)shouldComponentUpdate來(lái)避免重復(fù)渲染。這里跟redux是一樣的。
import React, {PropTypes} from 'react';
import createRebixComponent from '../config/createRebixComponent';
import UserStore from '../stores/UserStore';
import RebixConfigure from './RebixConfigure';
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = {
userInfo: {}
};
}
componentDidMount() {
var that = this;
var {actions} = that.props;
var mm = actions.getUserList(1234);
var mm2 = actions.beginEditUserInfo(1234);
actions.getPostList('absdf', 'sdf').then(function () {
debugger;
});
setTimeout(function () {
//直接訪問(wèn)Store中的數(shù)據(jù)
var userInfo = UserStore.getUserInfo(121);
that.setState({userInfo: userInfo});
}, 2000)
}
render() {
var userList = this.props.userList || [];
var postList = this.props.postList || [];
var userInfo = this.state.userInfo || {};
return (
<div>
aaa---{userInfo.name}
<br/>
bbb---
{userList.map(function (x) {
return <div>{x}</div>
})}
<hr/>
ccc---
{postList.map(function (x) {
return <div>{x}</div>
})}
</div>
);
}
}
export default Rebix.createComponent(RebixConfigure, Hello, {
actions: {
getUserList: 'user.getUserList', //請(qǐng)參考config文件中的配置。
getPostList: 'post.getPostList',
beginEditUserInfo: 'user.beginEditUserInfo'
},
props: {
userList: 'user.userList',
postList: 'user.postList'
}
});
原理
內(nèi)部實(shí)現(xiàn)還是使用Redux,只有一個(gè)唯一的Store,通過(guò)connect自動(dòng)完成對(duì)store數(shù)據(jù)變化的pub/sub機(jī)制。
License
MIT
聯(lián)系我
-
Email: [email protected]
