@duanyubin
2016-03-20T15:50:58.000000Z
字数 3873
阅读 407
项目总结
state
存放在一个唯一的store
中state
的唯一方法是,触发一个action
action
如何改变state
需要依靠reducer
/**
* 下方是reducer, 一个通过旧的`state`和已经触发的`action`生成新`state`的纯函数
*
* `state`的形状由业务决定,可以是数组或者对象,**重要的是,不可以修改state对象,而是返回一个新的对象**
*
*/
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}
// 创建store用于存放整个app的所有state.
// Its API is { subscribe, dispatch, getState }.
let store = createStore(counter)
// 可以手动订阅更新或者跟view层绑定
store.subscribe(() =>
console.log(store.getState())
)
// 触发action
store.dispatch({ type: 'INCREMENT' })
// 1
store.dispatch({ type: 'INCREMENT' })
// 2
store.dispatch({ type: 'DECREMENT' })
// 1
{
type: ADD_TODO,
payload: {
text: 'Build my first Redux app'
}
}
function addTodo(text) {
return {
type: ADD_TODO,
payload: {
text
}
};
}
// 实际发送 action
dispatch(addTodo(text));
function removeTodo(id) {
return (dispatch, getState) => {
return ajax()
.then((json) => {
dispatch({
type: REMOVE_TODO,
id
})
})
}
}
dispatch(removeTodo(id));
It provides a third-party extension point between dispatching an action, and the moment it reaches the reducer.
在dispatch
一个action
和此action
到达reducer
时,给第三方扩展提供切入点。
用于日志记录,异常处理,异步处理,路由等。
|-- actions
|-- components
|-- containers
|-- middleware
|-- reducers
|-- routes
|-- configureStore.js
|-- index.jsx
负责与redux交流的一个react component
react-redux提供了 Provider元件和connect方法
用在应用的根元素外面,负责传递唯一的Store给应用
const reducer = combineReducers(reducers);
const store = createStore(reducer);
class App extends Component {
render() {
return (
<Provider store={store}>
{() => <App />}
</Provider> );
}
}
- 将dispatch方法透过props的方式加到元件中
- 选取这个container需要state的哪一部分
import { increase, decrease}
function mapStateToProps(state) {
return { counter: state.counter };
}
function mapDispatchToProps() {
return {
increase: increase,
decrease
}
}
class CounterApp {
render() {
const { counter, dispatch } = this.props;
return (
<Counter counter={counter} /> );
}
}
export default connect(mapStateToProps, mapDispatchToProps)(CounterApp)
before:
// users.scss
@include foundation-button;
@include foundation-forms;
// detail.scss
@include foundation-forms;
after:
// mian.scss
:global {
@include foundation-form-prepostfix;
@include foundation-text-alignment;
@include foundation-global-styles;
....
}
// User.jsx
<div styleName="wrap">
<a className="button small" onClick={this.handleAddClick}>添加新用户</a>
</div>
// action.js
function requestCodes(id, pageNum = 1, dispatch) {
// return ajax({ url: `http://localhost:3100/inviteCodes.json` })
return ajax({
url: `http://baoming.ws.netease.com/admin/invitecode/list`,
body: { cid: id, pageNum }
})
.then((json) => {
dispatch({
type: type.REQUEST_CODES,
data: json.data,
id
});
return Promise.resolve(json);
}).catch(errorHandler.bind(null, dispatch));
}
// 获取邀请码
export function loadInviteCodes(id, pageNum) {
return (dispatch) => {
return requestCodes(id, pageNum, dispatch);
};
}
// 获取邀请码总数
export function fetchCodesCount(id) {
return (dispatch) => {
// return ajax({ url: `http://localhost:3100/count.json` })
return ajax({
url: `http://baoming.ws.netease.com/admin/invitecode/totalCount`,
body: { cid: id }
})
.then((json) => {
dispatch({
type: type.REQUEST_CODES_COUNT,
count: json.data
});
return Promise.resolve(json);
});
};
}
// errorHandler
import * as modal from '../actions/modal';
export default function errorHanlder(dispatch, fail) {
dispatch(modal.error({ msg: `${fail.msg}` }));
if (fail.code === -1 && window.location.hostname !== 'localhost') {
setTimeout(() => {
window.location.href = 'http://baoming.ws.netease.com/login/login';
}, 500);
}
const error = new Error(fail);
throw error;
}
// before
// action.js
function whatever() {
if(confirm('something')){
//....
}
}
// after
// action.js
function whatever(){
modal.confirm('something')
.then((result) => {
console.log(result)
})
}
// modal.js
const resolve = () => {}
const reject = () => {}
const promise = new Promise((res, rej) => {
resolve = res
reject = rej
})
function show() {}
function hide(result) {
resolve(result)
}
export function confirm(msg) {
return promise
}