react-native 从简单的事件分发来介绍redux

来源:互联网 发布:如东知品服饰有限公司 编辑:程序博客网 时间:2024/05/21 23:33

载请注明出处:王亟亟的大牛之路

这两天组里来了几个新人,有的用过redux,有的没用过,为了让他们上手或者理解的更透彻,就写了个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

演示效果:

理论知识:

http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html

http://www.jianshu.com/p/0e42799be566

http://www.jianshu.com/p/3334467e4b32

理论知识重复炒冷饭等于制造网络垃圾,所以贴上几篇我觉得写得不错的给大家瞅瞅

核心理念:

Store:应用只有一个单一的 Store,State是这个状态集合某一时刻的状态 
Action:改变state的载体,也是Store的数据源 
Reducer:更新Store的具体操作者

ok,你现在肯定云里雾里的,我们用代码边写边解释

项目结构:

Action相关

MathType

export const ADD_TYPE = 'ADD_TYPE';export const MINUS_TYPE = 'MINUS_TYPE';
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

这里是2个常量,”加类型”,”减类型”,我们每种action都有他相对应的类型,可以写在Action里也可以写一个类型对他进行划分,我习惯是拆的越细越好

MathAction

// action类型import * as types from '../type/MathType';// 每一个action方法返回一个新的"state"对象,他就是应用当前的状态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,    }};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Reducer相关

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;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

肉眼看起来很简单,这里接受两种类型的action一个是➕,一个是➖,每次他都会改变传入参数的值,而且是一定改变,一定会+10或者-10! 
reducer只是一个方法,传入什么,返回什么。结果是个恒定值,只要传入参数不变,返回参数一定也不变!

reducers

import  Mathreducer from './Mathreducer';import  {combineReducers} from 'redux';export default combineReducers({    mathStore: Mathreducer,});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这是一个reducer的大容器,你所有reducer丢一个方法里也不是不能处理,但是性能差加难以维护,所以redux提供combineReducers来帮你整合reducer


Store相关

store是个应用级持有的对象,所以我们把他放到了”根”页面里去做初始化,因为我们之后还会用到异步action,所以还用到redux-thunk的相关内容

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)        }    }    //前面一些只是对象,方法相关的操作,肉眼可以识别,Provider是让我们决定使用redux的一个原因,它可以让我们操作容器内的组件却不需要手动传递内容    //想想复杂应用来一个 4层以上的json要你你自己操作的话的工作量吧    render() {        return (            <Provider store={this.state.store}>                <Main/>            </Provider>        )    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

只需要在外面套一层,所有子控件的属性竟在掌握!


页面代码

import React from'react';import {connect} from 'react-redux';//加减的两种actionimport {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));    }    //状态变化时会被调用    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}}>                        按我会加                    </Text>                </TouchableHighlight>                <TouchableHighlight style={{marginTop: 30}} onPress={this.minusPress}>                    <Text style={{fontSize: 15}}>                        按我会减                    </Text>                </TouchableHighlight>                <Text style={{marginTop: 30, color: '#ffaa11'}}>{this.state.intvalue}</Text>            </View>        )    }}function select(store) {    return {        result: store.mathStore.result,    }}//connect方法建立数据与状态的关系,达到刷新ui的效果export  default  connect(select)(Main);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

这样这个简单的demo就讲完了,什么?看不懂,我也觉得 这说的是啥啊,过程都没讲清楚,ok 看下console你就明白了!

//首页被加载出来05-19 20:52:49.094 5992-24741/? I/ReactNativeJS: ---> Main render//页面点击了 “按我会加”05-19 20:52:57.746 5992-24741/? I/ReactNativeJS: ---> Main addPress//action得到了响应获取到了 100(正常的方法调用嘛?继续看!)05-19 20:52:57.747 5992-24741/? I/ReactNativeJS: ---> MainAction add intvalue 100//传递到了reducer获取到了触发的类型05-19 20:52:57.747 5992-24741/? I/ReactNativeJS: ---> mathReducer action.type ADD_TYPE//页面收到了state改变的讯息,回调被触发05-19 20:52:57.759 5992-24741/? I/ReactNativeJS: ---> Main shouldComponentUpdate//新的值是之前的100+reducer的10=11005-19 20:52:57.759 5992-24741/? I/ReactNativeJS: ---> Main shouldComponentUpdate this.state.intvalue 110//刷新数据05-19 20:52:57.759 5992-24741/? I/ReactNativeJS: ---> Main render//第二次操作,不解释了05-19 20:53:02.010 5992-24741/? I/ReactNativeJS: ---> Main minuPress05-19 20:53:02.010 5992-24741/? I/ReactNativeJS: ---> MainAction minus intvalue 11005-19 20:53:02.010 5992-24741/? I/ReactNativeJS: ---> mathReducer action.type MINUS_TYPE05-19 20:53:02.015 5992-24741/? I/ReactNativeJS: ---> Main shouldComponentUpdate05-19 20:53:02.015 5992-24741/? I/ReactNativeJS: ---> Main shouldComponentUpdate this.state.intvalue 10005-19 20:53:02.015 5992-24741/? I/ReactNativeJS: ---> Main render
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

action reducer本身看起来平淡无奇,但是在store内轮转使得我们省去了大量setState的人工操作,避免了各种不可描述的render().

但是 redux处理不好会各种多次render页面,之后的文章我会讲一讲异步的action和react-native优化

我是王亟亟!我们下篇见

有问题可以扫码加好友询问噢,非公众号,闲人勿扰! 

原创粉丝点击