轉(zhuǎn)載請(qǐng)注明出處:王亟亟的大牛之路
這兩天組里來了幾個(gè)新人棵里,有的用過redux润文,有的沒用過,為了讓他們上手或者理解的更透徹,就寫了個(gè)demo,代碼邏輯來源于https://github.com/ninty90/react-native-redux-demo
開篇前先安利
android:https://github.com/ddwhan0123/Useful-Open-Source-Android
react-native:https://github.com/ddwhan0123/Useful-Open-Source-React-Native
源碼地址:https://github.com/ddwhan0123/ReduxDemo
演示效果:
理論知識(shí):
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html
http://www.reibang.com/p/0e42799be566
http://www.reibang.com/p/3334467e4b32
理論知識(shí)重復(fù)炒冷飯等于制造網(wǎng)絡(luò)垃圾殿怜,所以貼上幾篇我覺得寫得不錯(cuò)的給大家瞅瞅
核心理念:
Store:應(yīng)用只有一個(gè)單一的 Store,State是這個(gè)狀態(tài)集合某一時(shí)刻的狀態(tài)
Action:改變state的載體典蝌,也是Store的數(shù)據(jù)源
Reducer:更新Store的具體操作者
ok,你現(xiàn)在肯定云里霧里的,我們用代碼邊寫邊解釋
項(xiàng)目結(jié)構(gòu):
Action相關(guān)
MathType
export const ADD_TYPE = 'ADD_TYPE';
export const MINUS_TYPE = 'MINUS_TYPE';
這里是2個(gè)常量头谜,"加類型","減類型"骏掀,我們每種action都有他相對(duì)應(yīng)的類型,可以寫在Action里也可以寫一個(gè)類型對(duì)他進(jìn)行劃分柱告,我習(xí)慣是拆的越細(xì)越好
MathAction
// action類型
import * as types from '../type/MathType';
// 每一個(gè)action方法返回一個(gè)新的"state"對(duì)象,他就是應(yīng)用當(dāng)前的狀態(tài)
export function add(intvalue) {
console.log('---> MainAction add intvalue ' + intvalue);
return {
type: types.ADD_TYPE,
result: intvalue,
}
};
export function minus(intvalue) {
console.log('---> MainAction minus intvalue ' + intvalue);
return {
type: types.MINUS_TYPE,
result: intvalue,
}
};
Reducer相關(guān)
MathReducer
import * as Type from'../type/MathType';
//初始化
const initState = {
result: 0
};
export default function mathReducer(state = initState, action = {}) {
switch (action.type) {
case Type.ADD_TYPE:
console.log('---> mathReducer action.type ' + action.type);
return {
...state,
result: action.result + 10,
};
break;
case Type.MINUS_TYPE:
console.log('---> mathReducer action.type ' + action.type);
return {
...state,
result: action.result - 10,
};
default:
return state;
}
}
肉眼看起來很簡(jiǎn)單截驮,這里接受兩種類型的action一個(gè)是?,一個(gè)是?际度,每次他都會(huì)改變傳入?yún)?shù)的值葵袭,而且是一定改變,一定會(huì)+10或者-10!
reducer只是一個(gè)方法乖菱,傳入什么坡锡,返回什么。結(jié)果是個(gè)恒定值窒所,只要傳入?yún)?shù)不變鹉勒,返回參數(shù)一定也不變!
reducers
import Mathreducer from './Mathreducer';
import {combineReducers} from 'redux';
export default combineReducers({
mathStore: Mathreducer,
});
這是一個(gè)reducer的大容器吵取,你所有reducer丟一個(gè)方法里也不是不能處理禽额,但是性能差加難以維護(hù),所以redux提供combineReducers來幫你整合reducer
Store相關(guān)
store是個(gè)應(yīng)用級(jí)持有的對(duì)象海渊,所以我們把他放到了"根"頁(yè)面里去做初始化,因?yàn)槲覀冎筮€會(huì)用到異步action,所以還用到redux-thunk
的相關(guān)內(nèi)容
import {Provider} from 'react-redux';
import {createStore, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import reducers from'./reducer/reducers';
const middlewares = [thunk];
const createSoreWithMiddleware = applyMiddleware(...middlewares)(createStore);
import React from 'react';
import Main from'./Main';
export default class App extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
store: createSoreWithMiddleware(reducers)
}
}
//前面一些只是對(duì)象绵疲,方法相關(guān)的操作,肉眼可以識(shí)別臣疑,Provider是讓我們決定使用redux的一個(gè)原因盔憨,它可以讓我們操作容器內(nèi)的組件卻不需要手動(dòng)傳遞內(nèi)容
//想想復(fù)雜應(yīng)用來一個(gè) 4層以上的json要你你自己操作的話的工作量吧
render() {
return (
<Provider store={this.state.store}>
<Main/>
</Provider>
)
}
}
只需要在外面套一層,所有子控件的屬性竟在掌握!
頁(yè)面代碼
import React from'react';
import {connect} from 'react-redux';
//加減的兩種action
import {add, minus} from './action/MathAction';
import {
Text,
View,
TouchableHighlight,
} from 'react-native';
class Main extends React.Component {
constructor(props) {
super(props);
this.addPress = this.addPress.bind(this);
this.minusPress = this.minusPress.bind(this);
//初始值讯沈,也可以是外部傳入
this.state = {
intvalue: 100,
}
}
addPress() {
console.log('---> Main addPress');
this.props.dispatch(add(this.state.intvalue));
}
minusPress() {
console.log('---> Main minuPress');
//dispatch(action) 方法更新 state
this.props.dispatch(minus(this.state.intvalue));
}
//狀態(tài)變化時(shí)會(huì)被調(diào)用
shouldComponentUpdate(nextProps, nextState) {
console.log('---> Main shouldComponentUpdate');
if (nextProps.result !== this.props.result) {
this.state.intvalue = nextProps.result;
console.log('---> Main shouldComponentUpdate this.state.intvalue ' + this.state.intvalue);
return true;
}
}
render() {
console.log('---> Main render');
return (
<View style={{justifyContent: 'center'}}>
<TouchableHighlight onPress={this.addPress}>
<Text style={{fontSize: 15}}>
按我會(huì)加
</Text>
</TouchableHighlight>
<TouchableHighlight style={{marginTop: 30}} onPress={this.minusPress}>
<Text style={{fontSize: 15}}>
按我會(huì)減
</Text>
</TouchableHighlight>
<Text style={{marginTop: 30, color: '#ffaa11'}}>{this.state.intvalue}</Text>
</View>
)
}
}
function select(store) {
return {
result: store.mathStore.result,
}
}
//connect方法建立數(shù)據(jù)與狀態(tài)的關(guān)系郁岩,達(dá)到刷新ui的效果
export default connect(select)(Main);
這樣這個(gè)簡(jiǎn)單的demo就講完了婿奔,什么?看不懂问慎,我也覺得 這說的是啥啊萍摊,過程都沒講清楚,ok 看下console你就明白了如叼!
//首頁(yè)被加載出來
05-19 20:52:49.094 5992-24741/? I/ReactNativeJS: ---> Main render
//頁(yè)面點(diǎn)擊了 “按我會(huì)加”
05-19 20:52:57.746 5992-24741/? I/ReactNativeJS: ---> Main addPress
//action得到了響應(yīng)獲取到了 100(正常的方法調(diào)用嘛冰木?繼續(xù)看!)
05-19 20:52:57.747 5992-24741/? I/ReactNativeJS: ---> MainAction add intvalue 100
//傳遞到了reducer獲取到了觸發(fā)的類型
05-19 20:52:57.747 5992-24741/? I/ReactNativeJS: ---> mathReducer action.type ADD_TYPE
//頁(yè)面收到了state改變的訊息笼恰,回調(diào)被觸發(fā)
05-19 20:52:57.759 5992-24741/? I/ReactNativeJS: ---> Main shouldComponentUpdate
//新的值是之前的100+reducer的10=110
05-19 20:52:57.759 5992-24741/? I/ReactNativeJS: ---> Main shouldComponentUpdate this.state.intvalue 110
//刷新數(shù)據(jù)
05-19 20:52:57.759 5992-24741/? I/ReactNativeJS: ---> Main render
//第二次操作踊沸,不解釋了
05-19 20:53:02.010 5992-24741/? I/ReactNativeJS: ---> Main minuPress
05-19 20:53:02.010 5992-24741/? I/ReactNativeJS: ---> MainAction minus intvalue 110
05-19 20:53:02.010 5992-24741/? I/ReactNativeJS: ---> mathReducer action.type MINUS_TYPE
05-19 20:53:02.015 5992-24741/? I/ReactNativeJS: ---> Main shouldComponentUpdate
05-19 20:53:02.015 5992-24741/? I/ReactNativeJS: ---> Main shouldComponentUpdate this.state.intvalue 100
05-19 20:53:02.015 5992-24741/? I/ReactNativeJS: ---> Main render
action reducer本身看起來平淡無(wú)奇,但是在store內(nèi)輪轉(zhuǎn)使得我們省去了大量setState的人工操作社证,避免了各種不可描述的render().
但是 redux處理不好會(huì)各種多次render頁(yè)面逼龟,之后的文章我會(huì)講一講異步的action和react-native優(yōu)化
我是王亟亟!我們下篇見