Redux集成setProps方法
@H_502_2@---- 适用于react和react-native开发作者:陈浩
联系:chenhao455@yeah.net @H_502_2@说明:在当前store里新增一个变量(我称之为新增props,下同)
当前redux使用方式
@H_502_2@在react和react-native中经常用到redux @H_502_2@我们用redux建立了一个store,用来存储项目数据,它相对项目的单页面是props项目入口文件
@H_502_2@index.html<!DOCTYPE html> <html> <head> <Meta charset="UTF-8"> <title> </title> </head> <body> <div id="root"></div> </body> </html>@H_502_2@index.js
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配置
@H_502_2@store/configureStore.jsimport { 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配置
@H_502_2@reducers/index.jsimport { combineReducers } from 'redux'; import orderDetail from './orderDetail'; import book from './book'; import app from './app'; const rootReducer = combineReducers({ orderDetail,book,app }); export default rootReducer;@H_502_2@reducers/app.js(reducers/book.js、 reducers/ orderDetail.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({},{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,下同)需要干这么工作:
- @H_502_2@1.Constants里面新建的Action常量
- @H_502_2@2.reducers/app.js,新增对该变量的处理方法switch-case再加一条case语句;
- @H_502_2@3.action/app.js里,新增一个方法,用来分发该常量;
- @H_502_2@4.Containers/app.js,引用上一步的方法,并调用;
新增props遇到的问题:
- @H_502_2@reducers/app.js和action/app.js里,新建的Action常量容易忘记引用
- @H_502_2@reducers/app.js里,每新增一个Action常量,就需要增加一条switch-case语句, switch-case语句结构相似,代码冗余了
- @H_502_2@action/app.js里,每新增一个Action常量,就需要增加类似 dispatch({type: TRACK_EVENT_ID,trackEventID: trackEventID}); 的代码,这样的代码会出现很多次
思考解决这个问题:
- @H_502_2@有个setState(obj)是不是很牛掰,想更新啥state就操作一下即可,咱们可以参考它的思路
- @H_502_2@setState更新state的;咱们写个setProps用来更新props不就行了嘛!
- @H_502_2@app、book、orderDetail,只写一个setProps的话,book页面,需要调用自己的setProps更新订单信息,也需要调用app.js的setProps更新联系人,都叫setProps就混淆了,所以分别可以叫setPropsApp、 setPropsBook、 setPropsDetail
修改前后的constants对比
@H_502_2@修改前的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';@H_502_2@修改后的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对比
@H_502_2@修改前import assign from 'object-assign'; import { GET_CLIENTINFO,{networkStatus: action.networkStatus}); } return state; }@H_502_2@修改后
import * as ActionTypes from '../constants/ActionTypes'; import assign from 'object-assign'; var initialState = { osType: '',//获取客服地址链接 }; export default function app(state = initialState,action){ if(action.type == ActionTypes.SET_PROPS_APP){ state = assign({},action.newObj); } return state; }
修改前后的actions/app.js对比
@H_502_2@修改前import {GET_CLIENTINFO,addressInfo }; } /*****************************下面才是真正的业务方法******************************/ ...@H_502_2@修改后
import * as ActionTypes from '../constants/ActionTypes'; /**************************只有一个dispatch Action 方法**************************/ export function setPropsApp(newObj){ return { type: ActionTypes.SET_PROPS_APP,newObj }; } /*****************************下面是真正的业务方法******************************/ ...
完整demo代码
- @H_502_2@以后提供
实际使用经验
- @H_502_2@App、Book、OrderDetail 3大页面值外的页面不需要再定义setPropsXXX,使用前3个页面定义的setPropsApp、 setPropsBook、 setPropsDetail即可;
- @H_502_2@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','detail',{remark:'备注信息22'}); console.log('data3',data);
以后更新store中的数据只需要一行代码
@H_502_2@setPropsApp({ variablesName : variablesValue }); @H_502_2@setPropsApp:更新APP页面的props变量方法setPropsApp、 setPropsBook、 setPropsDetail同理 @H_502_2@variablesName :要更新的变量名variablesValue :要更新的变量新值