Redux简介
Redux是继FB Flux 架构后推出的管理 React 数据流的亮眼之作。
可以说Redux是对Flux 架构的一些简化。 Redux 限定一个store,让应用中数据结果集中化,提高可控性。
Action、Reducer、及 Store
Redux 主要分为三个部分 Action、Reducer、及 Store. 下面以counter Sample核心Code为例.
Action
action 主要用来传递操作 State 的信息。 Action是一个plain object(空对象或者key/value键值对),
action内必须使用一个字符串类型的type字段。 当应用规模越来越大时,建议使用单独的模块或者文件来存放action。
核心Code
使用函数来产生action
export const ADD_ITEM = 'ADD_ITEM';
export const MINUS_ITEM = 'MINUS_ITEM';
export function addItem() {
console.log('action--' + 'addItem');
return {
type: ADD_ITEM,
}
}
export function minusItem() {
return {
type: MINUS_ITEM,
}
}
Reducer
可以认为Reducer是处理Action的逻辑操作。 Reducer一般为简单的处理函数,通过传入旧的state和action来更新state。
(previousState, action) => newState
核心Code
import {ADD_ITEM, MINUS_ITEM} from '../action/action';
export function counter(state = 0, action) {
console.log('reduce fuction...');
switch (action.type) {
case ADD_ITEM:
return state + 1;
case MINUS_ITEM:
return state - 1;
default:
return state;
}
}
export function counter1(state = 0, action) {
console.log('reduce fuction1...');
switch (action.type) {
case ADD_ITEM:
return state + 4;
default:
return state;
}
}
注意:不要在reducer里做如下操作: • 修改传入参数 • 执行有副作用的操作,如API请求和路由跳转 • 调用非纯函数,如Date.now()或Math.random()
Redux可以分多个Reducer分别处理不同module的逻辑,最后combineReducers,导出一个rootReducer
核心Code
import { combineReducers } from 'redux';
import {counter, counter1} from './counter';
const rootReducer = combineReducers({
counter1,
num: counter
});
export default rootReducer;
Store
Action 代表操作消息,Reducer 用来处理消息并更新State。
在 Redux 项目中,Store 是单一的。维护着一个全局的 State. 有如下功能:
- 维持应用state
- 提供getState()方法获取state
- 提供dispatch(action)方法更新state
- 通过subscribe(listener)注册监听器
- 通过subscribe(listener)返回的函数注销监听器
Store 是一个把 Action 和 Reducer 结合起来的对象。
核心Code
import { createStore, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import logger from 'redux-logger';
import reducer from '../reducers/index';
const createStoreWithMiddleware = applyMiddleware(
thunk
)(createStore);
export default function configureStore(initialState) {
console.log('store---' + 'configureStore');
const store = createStoreWithMiddleware(reducer, initialState);
return store;
}
Page中使用
class BaseApp extends Component {
render() {
const {counter, addItem, minusItem} = this.props;
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Clicked: {counter} times
</Text>
<TouchableHighlight style={styles.btn} onPress={addItem}>
<Text style=>Add</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.btn} onPress={minusItem}>
<Text style=>Minus</Text>
</TouchableHighlight>
</View>
);
}
}
function mapStateToProps(state) {
console.log('mapStateToProps...');
console.log('state:' + state.counter);
return {
counter: state.num,
}
}
function mapDispatchToProps(dispatch) {
console.log('mapDispatchToProps...');
console.log(CounterActions);
return bindActionCreators(CounterActions, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(BaseApp);
备注是redux源码中部分核心Code,用于理解bindActionCreators方法
// function bindActionCreator(actionCreator, dispatch) {
// return function () {
// console.log('***********');
// for(var i=0;i<arguments.length;i++){
// console.log(arguments[i]);
// }
// return dispatch(actionCreator.apply(undefined, arguments));
// };
// }
// function bindActionCreators(actionCreators, dispatch) {
// if (typeof actionCreators === 'function') {
// return bindActionCreator(actionCreators, dispatch);
// }
// if (typeof actionCreators !== 'object' || actionCreators === null) {
// throw new Error('bindActionCreators expected an object or a function, instead received ' + (actionCreators === null ? 'null' : typeof actionCreators) + '. ' + 'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?');
// }
// var keys = Object.keys(actionCreators);
// var boundActionCreators = {};
// for (var i = 0; i < keys.length; i++) {
// var key = keys[i];
// console.log('xxxxx---' + keys.length);
// console.log(key);
// var actionCreator = actionCreators[key];
// console.log(actionCreator);
// if (typeof actionCreator === 'function') {
// console.log('actionCreator is function...');
// boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);
// }
// }
// console.log('******************');
// console.log(boundActionCreators);
// return boundActionCreators;
// }
Redux相关lib
"react-redux": "^4.4.5", // connect function
"redux": "^3.5.2",
"redux-immutable": "^3.0.6", // 不可变state
"redux-logger": "^2.6.1", // 查看log
"redux-thunk": "^2.1.0" // action 里面返回json object的函数
在实际使用中感觉到:Redux对提示开发效率作用不大。但是你会惊喜的发现对问题的排查和维护是多么的方便和效率。
而且从redux-devtools 中打印出来的信息,还能很清晰的get到整个业务逻辑的运作。