combineReducers 对数据进行拆分管以及使用immutable.js
1 使用combineReaducers 整合reducers
import { combineReducers } from 'redux-immutable'; import { reducer as headerReducer } from '../common/header/store'; import { reducer as homeReducer } from '../pages/home/store'; import { reducer as detailReducer } from '../pages/detail/store'; import { reducer as loginReducer } from '../pages/login/store'; const reducer = combineReducers({ header: headerReducer, //对应的state保存在 header下 home: homeReducer, detail: detailReducer, login: loginReducer }); export default reducer;
2. 在store文件夹下建立index文件,把该文件夹下的内容,全部用index文件发出去:
import reducer from './reducer'; import * as actionCreators from './actionCreators'; import * as constants from './constants'; export { reducer, actionCreators, constants };
3 对应的获取数据也要多一层:
const mapStateToprops = (state)=>{ return { focused: state.header.focused } }
4. 使用immutable来改变state:先安装immutable(用在reducer中)
安装redux-immutable,在最外层的reducer中,将其中的state也变为immutable对象,
import { combineReducers } from 'redux-immutable';
import * as constants from './constants'; import { fromJS } from 'immutable'; //这里引入immutable const defaultState = fromJS({ //这里用fromJs将js对象改为immutable对象 focused: false, mouseIn: false, list: [], page: 1, totalPage: 1 }); export default (state = defaultState, action) => { switch(action.type) { case constants.SEARCH_FOCUS: return state.set('focused', true); //使用set改变数据,immutable对象的set方法,会结合之前immutable对象的值和设置的值,返回一个全新的对象 case constants.SEARCH_BLUR: return state.set('focused', false); case constants.CHANGE_LIST: return state.merge({ //改变多个数据 list: action.data, totalPage: action.totalPage }); case constants.MOUSE_ENTER: return state.set('mouseIn', true); case constants.MOUSE_LEAVE: return state.set('mouseIn', false); case constants.CHANGE_PAGE: return state.set('page', action.page); default: return state; } }
获取单个immutable对象:(当没有引入redux-immutable的时候 state是从最外层的reducer而来,还是普通的js对象)
const mapStateToprops = (state)=>{ return { focused: state.header.get('focused') } }
在组件中需要把immutable对象再改变回正常的js对象:(这种方法是引入看redux-immutable,然后在最外层的reducer中把state改成来 immutable对象,所以state可以使用getIn函数了,获取header的reducer下的focused)
const mapStateToProps = (state) => { return { focused: state.getIn(['header', 'focused']), login: state.getIn(['login', 'login']) } }
5 使用axios异步获取数据,放在 actioncreater中:
import * as constants from './constants'; import { fromJS } from 'immutable'; import axios from 'axios'; const changeList = (data) => ({ type: constants.CHANGE_LIST, data: fromJS(data), totalPage: Math.ceil(data.length / 10) }); export const getList = () => { return (dispatch) => { axios.get('/api/headerList.json').then((res) => { const data = res.data; dispatch(changeList(data.data)); //dispatch 使用了本文件中的函数,该函数不再对外 }).catch(() => { console.log('error'); }) } };
则前面组件调用方式为:
dispatch(actionCreators.getList());
因为有多个reducer 则对应的多个actionCreators,每个小store中 使用index 提供对外接口:
import { actionCreators } from './store';