redux更新store中的數據繁瑣,我整合了一些代碼,使更新store中的數據只須要一行代碼

Redux集成setProps方法

---- 適用於react和react-native開發
做者:陳浩
聯繫:chenhao455@yeah.nethtml

說明:在當前store裏新增一個變量(我稱之爲新增props,下同)react

當前redux使用方式

在react和react-native中常常用到reduxes6

咱們用redux創建了一個store,用來存儲項目數據,它相對項目的單頁面是propsredux

項目入口文件

index.htmlreact-native

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>&nbsp;</title>
</head>
<body>

<div id="root"></div>

</body>
</html>

index.jspromise

import {Promise,polyfill} from 'es6-promise'
import React,{Component} from 'react';
import { render } from 'react-dom';
import {Provider} from 'react-redux';

/*import containers*/
import App from './containers/App';

import configureStore from './store/configureStore';
const store =  configureStore();

appInit();
render(
    <Provider store={store} >
        <App/>
    </Provider>,
    document.getElementById('root')
);

redux store配置

store/configureStore.jsapp

import { createStore, applyMiddleware } from 'redux';
import thunk  from 'redux-thunk';

import rootReducer from '../reducers';

const createStoreWithMiddleware = applyMiddleware(
    thunk 
)(createStore);

export default function configureStore (initialState) {
    try{
        const store = createStoreWithMiddleware(rootReducer,initialState);
        return store;
    }catch(e){
        // alert(e);
        console.log(e);
    }
}

constants配置

/* APP Page Constants */
export const GET_CLIENTINFO = 'GET_CLIENTINFO';
export const GET_LOCATIONINFO = 'GET_LOCATIONINFO';
export const SET_NETWORK_STATUS = 'SET_NETWORK_STATUS';

/* Book Page Constants */
export const SET_CONTACT = 'SET_CONTACT';
/****************************************** 這裏省略了N多條常量聲明 */
export const INVOICE_HISTORY = 'INVOICE_HISTORY';

/* OrderDetail Page Constants */
export const GET_ORDERDETAIL = 'GET_ORDERDETAIL';
export const GET_INVOICE_PROGRESS = 'GET_INVOICE_PROGRESS';

reducers配置

reducers/index.jsdom

import { combineReducers } from 'redux';

import orderDetail from './orderDetail';
import book from './book';
import app from './app';

const rootReducer = combineReducers({
    orderDetail,
    book,
    app
});

export default rootReducer;

reducers/app.js(reducers/book.js、 reducers/ orderDetail.js與此相似)ide

import assign from 'object-assign';
import {
    GET_CLIENTINFO,
    /**********這裏省略了N多條類似語句*/
    SET_PROPS_APP
} from '../constants';

var initialState = {
    osType: '',//操做系統
    /**********這裏省略了N多變量*/
    customerServiceURL:'',//獲取客服地址連接 
};
export default function app(state = initialState, action) {
    switch (action.type) {
        case SET_PROPS_APP: //獲取客戶端信息
            return assign({}, state, action.newObj);

        /*************************** 這裏省略了N多條類似case語句*/

        case SET_NETWORK_STATUS:
            return assign({},state,{networkStatus: action.networkStatus});
    }
    return state;
}

actions/app.js (actions/book.js、 actions/ orderDetail.js與此相似)

import {GET_CLIENTINFO,GET_LOCATIONINFO,SET_NETWORK_STATUS,SET_PROPS_APP} from '../constants';

/**設置聯繫人*/
export function setContact(contactInfo) {
    return {
        type: ActionTypes.SET_CONTACT,
        contactInfo
    }
}

/*****************************此處省略N多個dispatch action方法******************************/

/**設置地址*/
export function setStartAddress(addressInfo) {
    return {
        type: ActionTypes.SET_START_ADDRESS,
        addressInfo
    };
}

/*****************************下面纔是真正的業務方法******************************/
...

當前store裏新增一個變量(我稱之爲新增props,下同)須要幹這麼工做:

  • 1.Constants裏面新建的Action常量spa

  • 2.reducers/app.js,新增對該變量的處理方法switch-case再加一條case語句;

  • 3.action/app.js裏,新增一個方法,用來分發該常量;

  • 4.Containers/app.js,引用上一步的方法,並調用;

新增props遇到的問題:

  • reducers/app.js和action/app.js裏,新建的Action常量容易忘記引用

  • reducers/app.js裏,每新增一個Action常量,就須要增長一條switch-case語句, switch-case語句結構類似,代碼冗餘了

  • action/app.js裏,每新增一個Action常量,就須要增長相似 dispatch({type: TRACK_EVENT_ID, trackEventID: trackEventID}); 的代碼,這樣的代碼會出現不少次

思考解決這個問題:

  • 有個setState(obj)是否是很牛掰,想更新啥state就操做一下便可,我們能夠參考它的思路

  • setState更新state的;我們寫個setProps用來更新props不就好了嘛!

  • app、book、orderDetail,只寫一個setProps的話,book頁面,須要調用本身的setProps更新訂單信息,也須要調用app.js的setProps更新聯繫人,都叫setProps就混淆了,因此分別能夠叫setPropsApp、 setPropsBook、 setPropsDetail

修改先後的constants對比

修改前的constants

/* APP Page Constants */
export const GET_CLIENTINFO = 'GET_CLIENTINFO';
export const GET_LOCATIONINFO = 'GET_LOCATIONINFO';
export const SET_NETWORK_STATUS = 'SET_NETWORK_STATUS';

/* Book Page Constants */
export const SET_CONTACT = 'SET_CONTACT';
/****************************************** 這裏省略了N多條常量聲明 */
export const INVOICE_HISTORY = 'INVOICE_HISTORY';

/* OrderDetail Page Constants */
export const GET_ORDERDETAIL = 'GET_ORDERDETAIL';
export const GET_INVOICE_PROGRESS = 'GET_INVOICE_PROGRESS';

修改後的constants

export const SET_PROPS_APP = 'SET_PROPS_APP';
export const SET_PROPS_BOOK = 'SET_PROPS_BOOK';
export const SET_PROPS_DETAIL = 'SET_PROPS_DETAIL';

修改先後的reducers/app.js對比

修改前

import assign from 'object-assign';
import {
    GET_CLIENTINFO,
    /**********這裏省略了N多條類似語句*/
    SET_PROPS_APP
} from '../constants';

var initialState = {
    osType: '',//操做系統
    /**********這裏省略了N多變量*/
    customerServiceURL:'',//獲取客服地址連接 
};
export default function app(state = initialState, action) {
    switch (action.type) {
        case SET_PROPS_APP: //獲取客戶端信息
            return assign({}, state, action.newObj);

        /*************************** 這裏省略了N多條類似case語句*/

        case SET_NETWORK_STATUS:
            return assign({},state,{networkStatus: action.networkStatus});
    }
    return state;
}

修改後

import * as ActionTypes from '../constants/ActionTypes';
import assign from 'object-assign';

var initialState = {
    osType: '',//操做系統
    /**********這裏省略了N多變量*/
    customerServiceURL:'',//獲取客服地址連接 
};

export default function app(state = initialState,action){
    if(action.type == ActionTypes.SET_PROPS_APP){
        state = assign({}, state, action.newObj);
    }
    return state;
}

修改先後的actions/app.js對比

修改前

import {GET_CLIENTINFO,GET_LOCATIONINFO,SET_NETWORK_STATUS,SET_PROPS_APP} from '../constants';

/**設置聯繫人*/
export function setContact(contactInfo) {
    return {
        type: ActionTypes.SET_CONTACT,
        contactInfo
    }
}

/*****************************此處省略N多個dispatch action方法******************************/

/**設置地址*/
export function setStartAddress(addressInfo) {
    return {
        type: ActionTypes.SET_START_ADDRESS,
        addressInfo
    };
}

/*****************************下面纔是真正的業務方法******************************/
...

修改後

import * as ActionTypes from '../constants/ActionTypes';

/**************************只有一個dispatch Action 方法**************************/
export function setPropsApp(newObj){
    return {
        type: ActionTypes.SET_PROPS_APP,
        newObj
    };
}

/*****************************下面是真正的業務方法******************************/
...

完整demo代碼

  • 之後提供

實際使用經驗

  • App、Book、OrderDetail 3大頁面值外的頁面不須要再定義setPropsXXX,使用前3個頁面定義的setPropsApp、 setPropsBook、 setPropsDetail便可;

  • setPropsApp、 setPropsBook、 setPropsDetail能夠繼續合併:

export function setProps(state,dataPage,newObj){
            state[dataPage] =  assign({}, state[dataPage], newObj);
        return state;
}

var data ={
    app:{version:1,name:'cbd'},
    book:{saleDays:30,orderAmountMoney:0},
    detail:{orderSerialId:"訂單流水號",remark:'備註信息'}
};

data = setProps(data,'app',{version:2});
console.log('data1',data);
data = setProps(data,'book',{saleDays:40});
console.log('data2',data);
data = setProps(data,'detail',{remark:'備註信息22'});
console.log('data3',data);

之後更新store中的數據只須要一行代碼

setPropsApp({ variablesName : variablesValue });

setPropsApp:更新APP頁面的props變量方法
setPropsApp、 setPropsBook、 setPropsDetail同理

variablesName :要更新的變量名variablesValue :要更新的變量新值

相關文章
相關標籤/搜索