一、reducer文件的处理
先安装 immutable 与 redux-immutable
yarn add immutable redux-immutable
安装好后,要在大树下将子树合并,在store文件夹的 reducer.js 文件中引入
import { combineReducers } from ‘redux-immutable‘
import { combineReducers } from ‘redux‘
import { fromJS } from ‘immutable‘
将子树的state 转为 immutable 类型数据
整个是个Map类型,hotCity 是 List 类型
const defaultState = fromJS({ hotCity: [], areas: [], city: ‘全国‘, })
以在城市列表页,以 redux 维护选择的城市这个状态,其所在子树的 reducer.js 文件如import { fromJS } from ‘immutable
import { fromJS } from ‘immutable‘
import {
GET_CITYINFO_DATA,
CHANGE_CITY_DATA,
} from ‘./actionTypes‘
const defaultState = fromJS({
hotCity: [],
areas: [],
city: ‘全国‘,
})
export default (state=defaultState,action) => {
if(action.type === GET_CITYINFO_DATA){
// return {
// ...state,
// hotCity: [...action.result.hotCity],
// areas: [...action.result.areas]
// }
let newList = state.setIn([‘hotCity‘],fromJS(action.result.hotCity))
return newList.setIn([‘areas‘],fromJS(action.result.areas))
//如果要再原来的基础上修改List数据,就要用 updataIn方法如下 插入两个 List
// let newList = newProjectInfo.updateIn([‘projectInfo‘],list => list.concat(fromJS(action.result.loadMore),fromJS(action.result.loadMore)))
}
if(action.type === CHANGE_CITY_DATA){
// return {
// ...state,
// city: action.city
// }
return state.setIn([‘city‘],action.city)
}
return state
}
其中注释掉的是不使用 immutable 的代码。第二个 import 引入的是 定义的 action.type 值,可以做到避免在一个大树下有相同的 type 值。其命名如下 :
export const GET_CITYINFO_DATA = ‘address/get_cityInfo_data‘
二、在城市列表页引入 store 内的数据
先引入 connect
import {connect} from ‘react-redux‘
再定义 mapState 与 mapDispatch。
import {CHANGE_CITY_DATA} from ‘pages/address/actionTypes‘
const mapState = (state) => {
return {
hotCity: state.getIn([‘address‘,‘hotCity‘]),
areas: state.getIn([‘address‘,‘areas‘]),
}
}
const mapDispatch = (dispatch) => {
return {
loadData () {
dispatch(loadListAsync(dispatch))
},
changeCity (city) {
dispatch({
type: CHANGE_CITY_DATA,
city
})
}
}
}
其中 loadData() 方法,请求了数据, changeCity() 方法 改变了所维护的城市状态
loadData() 的相关代码如下:
import { GET_CITYINFO_DATA, } from ‘./actionTypes‘ export const loadCityInfoAsync = (result) => { return { type: GET_CITYINFO_DATA, result } } export const loadListAsync = (dispatch) => { return () => { fetch(‘/api/position/city‘) .then(response => response.json()) .then(result => { dispatch(loadCityInfoAsync(result)) }) } }
三、对数据的渲染
对于 List 类型的数据,利用 map() 进行渲染
代码如下:
import React,{Component} from ‘react‘
import {connect} from ‘react-redux‘
import BScroll from ‘better-scroll‘
import {AddressContainer} from ‘./styledComponents‘
import {loadListAsync} from ‘pages/address/actionCreator‘
import {CHANGE_CITY_DATA} from ‘pages/address/actionTypes‘
const mapState = (state) => {
return {
hotCity: state.getIn([‘address‘,‘hotCity‘]),
areas: state.getIn([‘address‘,‘areas‘]),
}
}
const mapDispatch = (dispatch) => {
return {
//请求数据
loadData () {
dispatch(loadListAsync(dispatch))
},
//改变redux中所保存的城市信息
changeCity (city) {
dispatch({
type: CHANGE_CITY_DATA,
city
})
}
}
}
class AddressContent extends Component {
render(){
// 将 this.props 内的内容解构出来
let { hotCity, areas, changeCity, handleClick } = this.props
//为在一页显示就没有进一步拆分,看不惯还请见谅
return (
// 绑定 better-scroll 的滚动根元素
<AddressContainer className="address-com-page" ref={el => this.scrollEl = el}>
<div>
<div>
<div className="address-tit">定位城市</div>
<div className="address-hot">
<span>定位失败</span>
</div>
</div>
<div>
<div className="address-tit" ref="hot">热门城市/区域</div>
<div className="address-hot">
{
// 对 hotCity 进行渲染,先判断这个数据是否存在,存在再渲染
// 数据是一个 List ,里面是个 Map , 里面的 cities 的值 是一个 List 类型,取得后直接进行map()
hotCity.get(0) && hotCity.getIn([0,‘cities‘]).map((v,i) => {
return (
// 绑定点击事件,选取所点击的城市 changeCity()
// handleClick() 是路由跳转,跳回首页
// cities 的每个子元素都是 Map ,利用 get() 来获取值
<span key={ v.get(‘cityId‘) }
onClick={() => {
changeCity(v.get(‘name‘))
handleClick()
}} >
{ v.get(‘name‘) }</span>
)
})
}
</div>
</div>
<div>
{
// 对按字母顺序排列的城市列表进行渲染
areas.map((v,i) => {
return (
<div key={v.get(‘prefix‘)}>
{/* 将小写字母转为大写 */}
<div className="address-tit">{ v.get(‘prefix‘).toUpperCase() }</div>
<ul className="address-detail">
{
// 渲染城市列表,并绑定点击事件
v.get(‘cities‘).map((v,i) => {
return (
<li key={v.get(‘cityId‘)}
onClick={() => {
changeCity(v.get(‘name‘))
handleClick()
}}>{ v.get(‘name‘) }</li>
)
})
}
</ul>
</div>
)
})
}
</div>
</div>
</AddressContainer>
)
}
componentDidMount(){
// 调用 mapDispatch 中的loadData() 方法,获取数据
this.props.loadData()
this.bScroll = new BScroll(this.scrollEl,{
click: true,
})
}
}
export default connect(mapState,mapDispatch)(AddressContent)
至此城市列表页就渲染出来了。
以上就是利用 immutable 处理 redux 的 过程!
如果有问题,欢迎指出。
在 react 项目里应用 immutable 对 redux 进行处理,对 List 数据渲染的问题
原文:https://www.cnblogs.com/wertantan/p/10035812.html