ReactNative 之搭配框架 Redux

祁远
2023-12-01

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={{ alignSelf: 'center' }}>Add</Text>
                </TouchableHighlight>
                <TouchableHighlight style={styles.btn} onPress={minusItem}>
                    <Text style={{ alignSelf: 'center' }}>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;
// }

Demo Code下载

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到整个业务逻辑的运作。

Redux

Redux CN

React 数据流管理架构之 Redux 介绍

Redux核心概念

React+Redux系列教程

看漫画学 Redux

 类似资料: