在 react 项目里如何配合immutable在redux中使用
一、reducer文件的处理
先安装 immutable 与 redux-immutable
yarn add immutable redux-immutable
我们可能会在很多地方定义子树,这就需要在大树下将它们合并,在store文件夹的 reducer.js 文件中引入
import { combineReducers } from 'redux-immutable'
import { combineReducers } from 'redux'
export default combineReducers({
homepage,
address,
})
import { fromJS } from 'immutable'
将子树的state 转为 immutable 类型数据
整个 defaultState 是个Map类型,hotCity 是 List 类型
const defaultState = fromJS({
hotCity: [],
areas: [],
city: '全国',
})
以在城市列表页,以 redux 维护选择的城市这个状态,其所在子树的 reducer.js 文件引入 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() 方法是异步的请求数据,如果要想异步的请求数据则需要引入 中间件,这里用的是 redux-thunk ,同时需要引入 redux 的 applyMiddleware ,将中间件加上
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import reducers from './reducers'
const store = createStore(reducers,applyMiddleware(thunk))
export default store
//这是 store 文件夹下的 index.js 文件,暴露 store
这时就可以在action时异步的请求数据,redux-thunk会检测dispatch的内容,如果是个对象就直接让其正常向后执行,如果是函数,则会在函数执行完后,再次dispatch再正常后流。
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中使用的更多相关文章
- 搭建React项目(一):在网页中使用
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 在react项目中使用redux-thunk,react-redux,redux;使用总结
先看是什么,再看怎么用: redux-thunk是一个redux的中间件,用来处理redux中的复杂逻辑,比如异步请求: redux-thunk中间件可以让action创建函数先不返回一个action ...
- React项目中实现右键自定义菜单
最近在react项目中需要实现一个,右键自定义菜单功能.找了找发现纯react项目里没有什么工具可以实现这样的功能,所以在网上搜了搜相关资料.下面我会附上完整的组件代码. (注:以下代码非本人原创,具 ...
- React项目实战:react-redux-router基本原理
React相关 React 是一个采用声明式,高效而且灵活的用来构建用户界面的框架. JSX 本质上来讲,JSX 只是为React.createElement(component, props, .. ...
- react项目结合echarts,百度地图实现热力图
一.最近在一个react项目(antd pro)中需要展示一个热力地图.需求是: 1.热力地图可缩放: 2.鼠标点击可以展示该点地理坐标,及热力值. 3.初始化时候自适应展示所有的热力点. 4.展示热 ...
- React 项目引入 Dva
背景 现在手上在做的 React 项目因为年代久远,用的 Redux,写代码的体验不太好,所以想升级一下引入 dva.以往使用 dva 都是使用 dva-cli 直接生成 dva 项目,或者在使用 a ...
- 使用Facebook的create-react-app脚手架快速构建React开发环境(ant.design,redux......)
编程领域中的“脚手架(Scaffolding)”指的是能够快速搭建项目“骨架”的一类工具.例如大多数的React项目都有src,public,webpack配置文件等等,而src目录中又包含compo ...
- 【Webpack2.X笔记】 配合react项目进行配置
前言: 本文是自己在工作中使用webpack进行react开发项目构建的一些经验总结,做以记录防范后续踩坑. 如果您还没有webpack相关基础,请先移步 入门Webpack,看这篇就够了 进行基础学 ...
- React项目的最佳实践
项目代码 从零开始简书项目 从我第一次接触vue这个框架已经过了快一年的时间,陪伴我从前端小白到前端工程师,前端时间也是使用了 ts+vue这样的组合写代码,明显感觉vue与ts似乎没有产生比较好 ...
随机推荐
- TreeSet类的排序
TreeSet支持两种排序方法:自然排序和定制排序.TreeSet默认采用自然排序. 1.自然排序 TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间大小关系, ...
- HTTP_4_返回结果的HTTP状态码
状态码:返回请求结果. 状态码种类繁多,以下总结常用的状态码: 类别 信息性状态码 1XX 服务器接受请求,继续处理 成功状态码 200 OK 请求处理成功,并返回资源(响应报文中 ...
- 金蝶K3 V12.2版本,对已发生业务单据的物料启用辅助计量单位
/****************************************************************************** 联达双计量单位 yLD_K3Data_S ...
- 【iOS】iOS 调试快速定位程序在哪崩溃
iOS 开发过程中经常遇到程序崩溃.快速定位程序在哪崩溃的步骤如下: 1. 2. 3. 这样设置后,程序崩溃时会定位到崩溃的语句,如下: 原文链接:iOS开发何如在调试的时候轻松找到程序在哪里崩溃
- SpringBoot Jar包瘦身 - 跟大文件说再见!
前言 SpringBoot部署起来配置非常少,如果服务器部署在公司内网,上传速度还行,但是如果部署在公网(阿里云等云服务器上),部署起来实在头疼.就是 编译出来的 Jar 包很大,如果工程引入了许多开 ...
- 【POJ - 2456】Aggressive cows(二分)
Aggressive cows 直接上中文了 Descriptions 农夫 John 建造了一座很长的畜栏,它包括N (2 <= N <= 100,000)个隔间,这些小隔间依次编号为x ...
- (转)Linux LVM逻辑卷配置过程详解(创建、扩展、缩减、删除、卸载、快照创建)
一.预备知识 LVM全称为Logical Volume Manager 逻辑卷管理器,LVM是Linux环境中对磁盘分区进行管理的一种机制,是建立在硬盘和分区之上.文件系统之下的一个逻辑层,可提高磁盘 ...
- Docker入门学习笔记
Docker 什么是Docker 虚拟化技术 在计算机中,虚拟化是一种资源管理技术,将计算机中的各种实体资源如:CPU.硬盘.内存等予以抽象.转换后呈现出来打破实体结构间的不可切割的障碍,使用户可以比 ...
- 【一些小常识】Linux文件目录的通配符用法/*
在使用linux命令的时候,一时有点搞不清*的用法,于是整理记录下,在做jenkins 持续集成时还是很有用的 “*”在通配符中是最常用的一种,主要整理下在使用Linux命令时,文件夹目录的用法. 1 ...
- DevOps实施历程-v1.0
有AF项目的成功案例(DevOps实施历程-半自动化),公司新项目全部依此为模板,实现了从代码到安装的自动化流水线,为此我输出了Jenkins自动化指南.AF项目指南等文档,方便大家查阅和参 ...