使用immutable.js和redux-immutable来管理state中的状态,并进行每个模块state的拆分
安装immutable
npm install immutable --save
安装redux-immutable
npm install redux-immutable
在App.js中引入 react-redux中的Provider ,引入store中的index.js这个store是所以小的store的集合
import React, { Fragment } from 'react'
import { Provider } from 'react-redux'
import Header from './header/index'
import store from './store'
function App() {
return(
// 当不需要外层div时,需要引入Fragment,来包裹着里面的元素,
// 并且不在DOM中增加额外节点
<Fragment>
{/* Provider里面的所有组件都可以使用store里面的数据 */}
<Provider
store={store}
>
<Header></Header>
</Provider>
</Fragment>
)
}
最外面的store中的分别创建一个index.js和一个reducer.js文件
// index.js
import {createStore,compose,applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducer';
// window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ 开启redux devtools 调试模式,
// 可以实时监听到state里值的改变
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,
composeEnhancers(
applyMiddleware(thunk)
)
);
export default store;
// reducer.js
// combineReducers把小的reducer合并成大的reducer
import {combineReducers} from 'redux-immutable'
//es6中的as可以给变量重新取名
import {reducer as headerReducer} from '../header/store'
const reducer = combineReducers({
header:headerReducer, // 这个header 就是对应header模块中state,可以通过getInt(['header', '需要获取到的值'])
})
export default reducer;
在属于header模块中简历一个store文件夹,里面新建4个js文件
index.js 文件负责把state暴露出去
import reducer from './reducer'
import * as actionCreators from './actionCreators';
import * as constant from './actionTypes';
export {reducer,actionCreators,constant}
actionTypes.js 负责状态的类型,注意:每个小模块的类型管理字段不能一样,不然会导致其他模块中的state状态随之改变
export const CHANGE_HOME_DATA = 'CHANGE_HOME_DATA';
export const ADD_ARTICLE_LIST = 'ADD_ARTICLE_LIST';
export const TOGGLE_SCROLL_TOP = 'TOGGLE_SCROLL_TOP';
actionCreators.js 文件主要编辑改变state的逻辑方法
import axios from 'axios';
import * as constants from './actionTypes'
const addHomeList = (list, page)=>({
type: constants.ADD_ARTICLE_LIST,
paylod: {
list,
page
}
})
reducer.js 监听actionType里面的状态,改变state里面的值
import {fromJS,} from 'immutable';
import * as constants from './actionTypes'
const defaultState=fromJS({
topicList:[],
articleList:[],
recommendList:[],
articlePage:1,
isShow:false
})
export default (state=defaultState, action)=>{
const { action, paylod } = action
switch(action.type){
case constants.ADD_ARTICLE_LIST:
return state.merge({
articleList: state.get('articleList').concat(paylod.list),
articlePage: paylod.page
})
case constants.TOGGLE_SCROLL_TOP:
return state.set('isShow',action.show)
default:
return state;
}
}
在header文件中的index.js
引入connect进行store连接
//connect方法是提供组件与store进行连接
import { connect } from 'react-redux';
import { actionCreators } from './store';
function Header(props) {
const { topicList, articlePage } = props
const { addHomeListDsp} = props
return(
<div onClick={ () => addHomeListDsp(topicList, articlePage ++)}>
增加
</div>
)
}
//通过connect与store进行连接数据,并且映射到props上面
//state指的是store里面所有数据
const mapState = (state)=>({
// 获得header模块中的state值
topicList: state.getIn(['header','topicList']),
articlePage: state.getIn(['header','articlePage'])
//topicList:state.get('header').get('topicList') 也可以这样写
})
//组件在跟store连接时,要改变store里面的内容就要调用dispatch方法
const mapDispatch = (dispatch)=>({
//
addHomeListDsp (list, page){
const action = actionCreators.addHomeList(list, page);
dispatch(action)
},
})
export default connect(mapState,mapDispatch)(Header);