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 = (
<Provider store={store}>
<Router history={skHistory}>
<Route path="/" component={MainWindow}>
<Route path="headline_drafts/:id/edit" component={HeadlineEditor}/>
<Route path="headlines/:id" component={HeadlineDetail} />
<Route path="headlines" component={HeadlineList}/>
<Route path="users/:id" component={User}>
<Route path="articles" component={UserArticlesList} />
<Route path="collections" component={UserCollectionsList} />
</Route>
<Route path="operation_activities_red_packet/:id" component={RedPacket}/>
<Route path="danbai_packet/:id" component={DanbaiPacket} />
</Route>
</Router>
</Provider>
);
页面组件
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 (
<div className="SK-danbai-container">
aaa
</div>
);
}
});
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_action
define("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_action
define("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初始值
也可以使用componentWillReceiveProps
define('Components/Example', function(require, exports) {
var Example = React.createClass({
getInitialState: function() {
return {
};
},
componentWillReceiveProps: function() {
},
componentDidMount: function() {
},
render: function() {
const { rules = [] } = this.props;
return (
<div>
example
{
rules.map((item, index) => {
return (
<div key={ index }>
id: { item.id },
type: { item.type }
</div>
)
})
}
</div>
);
}
});
return Example;
});
在父组件中引入,传入danbaiPacketDetail.rules
<Example rules={ 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 > 自身的modal
3.this.props.params.id,this.props.location.query只能在Route中的组件获取.
4.对每个接口做错误处理.
5.对一些可能先返回undefined的值做保护,可以用解构赋值初始值.
const {a = []} = this.props;
6.post之后一般有回调,再重新dispatch获取接口,或者直接在post接口中callbackc处理.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。