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

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

这两天组里来了几个新人,有的用过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';

这里是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,
    }
};

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;
    }
}

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

reducers

import  Mathreducer from './Mathreducer';

import  {combineReducers} from 'redux';

export default combineReducers({
    mathStore: Mathreducer,
});

这是一个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>
        )
    }
}

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


页面代码

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));
    }

    //状态变化时会被调用
    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);

这样这个简单的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=110
05-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 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本身看起来平淡无奇,但是在store内轮转使得我们省去了大量setState的人工操作,避免了各种不可描述的render().

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

我是王亟亟!我们下篇见

有问题可以扫码加好友询问噢,非公众号,闲人勿扰!
这里写图片描述

猜你喜欢

转载自blog.csdn.net/ddwhan0123/article/details/72558752
今日推荐