react-redux用于管理和修改应用程序的状态
三大原则

  • 单一数据源
  • 状态是只读的
  • 状态修改均由纯函数完成

Redux核心api

1
2
import { createStore } from 'redux'
const store = createStore(reducers)
  • getState():获取 store 中当前的状态。
  • dispatch(action):分发一个 action,并返回这个 action,这是唯一能改变 store 中数据的
    方式。
  • subscribe(listener):注册一个监听者,它在 store 发生变化时被调用。
  • replaceReducer(nextReducer):更新当前 store 里的 reducer,一般只会在开发模式中调用
    该方法。

React-Redux

connect()

middleWare(深度阅读)

action

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import fetchJsonp from 'fetch-jsonp'
export default {
getBannerList: function(cb){
/**
* 根据请求的时间戳获取banner列表
*/
fetchJsonp('https://api.douban.com/v2/movie/in_theaters')
.then(function(res){
return res.json()
})
.then((data) => {
cb(data)
})
.catch((error) => {
console.log(error)
})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import api from '../reducers/api'
function getBannerList(res){
return {
type: 'HOME_GET_BANNER_LIST',
data: res.subjects
}
}
export function fetchBanner(){
return (dispatch) => {
api.getBannerList(function(res){
dispatch(getBannerList(res));
})
}
}

reducer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const initialState = {
banner: [],
nowplay: [],
coming: []
}
export default function homeState(state = initialState,action){
switch (action.type){
case 'HOME_GET_BANNER_LIST':
return Object.assign({},state,{
banner: action.data
});
case 'HOME_GET_NOWPLAYING_LIST':
return Object.assign({},state,{
nowplay: action.date.films
});
case 'HOME_GET_COMINGSOON_LIST':
return Object.assign({},state,{
coming: action.date.films
});
default:
return state;
}
}

index.js

1
2
3
4
5
6
import { combineReducers } from 'redux'
import homeState from './home'
export default combineReducers({
homeState
})

store

1
2
3
4
5
6
7
8
9
10
import { createStore,applyMiddleware,combineReducers } from 'redux'
// 中间件,有了这个就可以支持异步action
import thunk from 'redux-thunk';
import reducer from '../reducers/index'
var store = createStore(
reducer,
applyMiddleware(thunk)
);
export default store;

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import React,{ Component,PropTypes }from 'react'
import Header from '../components/Header.jsx'
import { Link } from 'react-router'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import * as actions from '../redux/actions/home'
import '../styles/home.sass'
let _key = 0;
class Home extends Component{
constructor(props,context){
super(props,context);
}
componentDidMount(){
this.props.actions.fetchBanner()
const { banner } = this.props;
}
render(){
return(
)
}
}
//取出state
const mapStateToProps = (state) => {
return {
banner:state.homeState.banner
nowplay:state.homeState.nowplay,
coming:state.homeState.coming
}
}
//dispatch action 更新state
const mapDispatchToProps = (dispatch) => {
return {
actions: bindActionCreators(actions,dispatch)
}
}
const mapDispatchToProps = (dispatch) => {
return {
onSwitchColor: (color) => {
dispatch({ type: 'CHANGE_COLOR', themeColor: color })
}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(Home);