main.js
1.引入Route,createStore,combineReducers
const {Router, Route, Redirect, IndexRoute, browserHistory} = ReactRouter;const {Provider, connect} = ReactRedux;const { createStore, combineReducers, applyMiddleware, compose} = Redux;const {syncHistoryWithStore, routerMiddleware, routerReducer, push } = ReactRouterRedux;const thunkMiddleware = require('redux-thunk');
2.引入组件和reducer
const DanbaiPacket = require('Containers/DanbaiPacket');const DanbaiPacket = require('Containers/DanbaiPacket');
3.绑定reducer,store
const reducer = combineReducers({ routing: routerReducer, localizationReducer: LocalizationReducer, accountReducer: AccountReducer, notificationReducer: NotificationReducer, headlineDetailReducer: HeadlineDetailReducer, headlineEditorReducer: HeadlineEditorReducer, headlineListReducer: HeadlineListReducer, userCollectionsReducer: UserCollectionsReducer, userArticlesReducer: UserArticlesReducer, signInPopupReducer: SignInPopupReducer, notifyMessageReducer: NotifyMessageReducer, redPacketReducer: RedPacketReducer, danbaiPacketReducer: DanbaiPacketReducer});const middleware = routerMiddleware(browserHistory);let initState = {};let store = createStore( reducer, {}, compose( applyMiddleware(thunkMiddleware, middleware), (window.RAILS_ENV === 'development' && window.devToolsExtension) ? window.devToolsExtension() : f=>f ));
4.Router结构
var routes = ();
页面组件
1.define这个组件
引入routerAction, connect做reducer连接引入action中的函数getDanbaiPacket,dispatch到action中处理数据this.props获取reducer中的数据组件上componentWillReceiveProps会受到reducer发来的数据,nextProps包含发来的信息.define("Containers/DanbaiPacket", function(require, exports) { const { routerActions } = ReactRouterRedux; const { connect } = ReactRedux; const { getDanbaiPacket } = require('Actions/DanbaiPacketAction'); var DanbaiPacket = React.createClass({ getInitialState: function() { return { }; }, componentDidMount: function() { this.props.dispatch(getDanbaiPacket(this.props.params.id)); }, render: function() { const { localization, current_account, danbaiPacketDetail } = this.props; return (aaa); } }); function mapStateToProps(state, ownProps) { return { localiztion: state.localizationReducer.languages[state.localizationReducer.languages.current], current_account: state.accountReducer.current_account, danbaiPacketDetail: state.danbaiPacketReducer.danbaiPacketDetail }; } return connect(mapStateToProps)(connect(null, routerActions)(DanbaiPacket));});
2.action
定义Action函数定义type字段字符串定义dispatch的函数,返回一个高阶函数,传入dispatch和getState,再dispatch到reducer处理数据return出type字段和函数,供reducer和组件使用.post类型的请求,或者不需要将数据挂载到reducer函数上的,不需要dispatch到reducer处理,直接用callback处理返回的数据.//= require ../../util/fetch_posts//= require ./notify_message_actiondefine("Actions/DanbaiPacketAction", function(require, exports) { const fetch = require('util/FetchPosts'); const { addNotifyMesaage } = require('Actions/NotifyMessageAction'); const INIT_DANBAI_PACKET = "INIT_DANBAI_PACKET"; function initDanbaiPacket(data) { return { type: INIT_DANBAI_PACKET, data: data }; } function getDanbaiPacket(id, callback) { return (dispatch, getState) => { fetch.get({ url: '/api/events/' + id + ',json', dataType: 'json', data: { sonkwo_client: 'web' }, success: function(res) { dispatch(initDanbaiPacket(res)) }, error: function(xhr) { if (xhr.status === 404) { dispatch(addNotifyMesaage("wufazhaodaoziyuan")); } } }); } } return { INIT_DANBAI_PACKET, getDanbaiPacket }});
3.reducer
从action引入type字符串定义reducer函数,即可以在组件中被获取的数据每个reducer函数都会return出一个对象,这就是这个函数的值,要用Object.assign({}, state, action.data)state的值会变化,直接action.data的话,那就只有这一个值.可以用Object.assign({}, state, {rules: action.data}),这样挂载再reducer函数上的key为rules.只要挂载再reducer函数上的key值有变化,只要有dispatch,就会触发组件render即使有两个reducer处理函数,也是以dispatch为准,dispatch后会触发reducer处理函数,触发组件render.//= require ../actions/danbai_packet_actiondefine("Reducers/DanbaiPacketReducer", function(require, exports) { const { INIT_DANBAI_PACKET } = require('Actions/RedPacketAction'); const { combineReducers } = Redux; function danbaiPacketDetial(state={}, action) { switch (action.type) { case INIT_DANBAI_PACKET: return Object.assign({}, state, action.data); default: return state; } } return combineReducers({ danbaiPacketDetial: danbaiPacketDetial });});
4.子组件
define子组件使用解构赋值,给rules初始值也可以使用componentWillReceivePropsdefine('Components/Example', function(require, exports) { var Example = React.createClass({ getInitialState: function() { return { }; }, componentWillReceiveProps: function() { }, componentDidMount: function() { }, render: function() { const { rules = [] } = this.props; return (example { rules.map((item, index) => { return (); } }); return Example;});id: { item.id }, type: { item.type }) }) }
在父组件中引入,传入danbaiPacketDetail.rules
问题总结
1.所有请求都把数据挂在了reducer函数上,且都直接返回,造成数据杂糅,key值冲突,不易处理逻辑,
又造成重复render.解决:1.post请求或者不需要处理返回数据的,直接callback执行回掉,在action中不需要dispatch到reducer处理.2.reducer处理数据时,return出来的值整个值,使用Object.assign({}, state, action.data),把数据全部返回.
2.Modal的ErrorPopup只需要有一个,error为this.state.error,mode为"simple"则样式自己写.
层叠顺序为:SignInPopup > ErrorPopup > 自身的modal3.this.props.params.id,this.props.location.query只能在Route中的组件获取.4.对每个接口做错误处理.5.对一些可能先返回undefined的值做保护,可以用解构赋值初始值.const {a = []} = this.props;
6.post之后一般有回调,再重新dispatch获取接口,或者直接在post接口中callbackc处理.