immutable
的进阶使用
- 下面我来展示一下,在深层次的
Map
或者List
结构中,想要修改深层次的数据,如何实现呢?
- 提供一个思路: 一层一层的改,首先获取第一层数据,再获取第二层数据,通过链式结构的形式修改数据
案例展示:
- 这个是一个修改信息数据的
Demo
,使用immutable
来实现,但是源数据是一个复杂的Map
数据结构
import React, { Component } from 'react' import { Map, List } from 'immutable' export default class App extends Component { state = { info: Map({ name: 'Lam', location: Map({ province: '广东', city: '江门' }), favor: List(['唱', '跳', 'Rap', '篮球']) }) } render() { return ( <div> <h1>修改地址</h1> <button onClick={()=>{ // 点击修改深层次的数据 this.setState({ /* 首先获取外层数据,再获取深层数据,最后再修改深层数据, 获取要修改的数据对象,再修改数据本身 */ // 修改第一层数据 info:this.state.info.set('name','肥林') // 修改第二层数据(首先修改(获取set)localtion,再获取(get)要修改的数据,最后再修改数据) .set('location',this.state.info.get('location').set('city','开平')) }) }}>修改</button> {/* 展示数据(Map和List) */} <div> 姓名:{this.state.info.get('name')} <br /> {/* 链式结构调用深层次的数据 */} 地址:{this.state.info.get('location').get('province')} -{this.state.info.get('location').get('city')} <br /> {/* List的循环遍历展示 */} 爱好:{this.state.info.get('favor').map((item, index) => { return <li key={item}> {item} <button onClick={() => { console.log(index); // 删除数据(List) this.setState({ // 获取要修改的数据对象,再修改数据本身 info:this.state.info.set("favor", this.state.info.get("favor").splice(index,1)) }) }}>删除</button> </li> })} </div> </div> ) } }
|
结果展示:
但是由代码层面我们也可以看出,这样写代码过于复杂,如果数据结构在复杂一点,那么代码量就会非常的多,不利于维护,由此引出下面的解决办法(fromJS
的基本使用)
fromJS
的基本使用
官方文档
fromJS
能将一个复杂的数据类型结构转化为Map-List
结构(深层次),就不需要我们自己一步一步的再数据中套Map
和List
了,并且里面提供一些方法(setIn
,updataIn
..),可以帮助我们直接修改深层次里面的数据
修改后的案例代码
import React, { Component } from 'react' import { fromJS } from 'immutable' export default class App extends Component { state = { info: fromJS({ name: 'Lam', location: { province: '广东', city: '江门' }, favor: ['唱', '跳', 'Rap', '篮球'] }) }
componentDidMount() { console.log('使用fromJS转化后的数据:',this.state.info) }
render() { return ( <div> <h1>修改地址</h1> <button onClick={()=>{ // 点击修改深层次的数据 this.setState({ // 修改第一层数据 info:this.state.info.set('name','肥林') /* 修改第二层数据(使用setIn修改深层次的数据,第一个参数为数组,里面包含数据的层级) 下面就是修改 location 里面的 city 的数据, 修改为开平 */ .setIn(['location','city'],'开平') }) }}>修改</button> {/* 展示数据(Map和List) */} <div> 姓名:{this.state.info.get('name')} <br /> {/* 调用深层数据同样可以使用getIn,数组里面的数据一致表示数据层级 */} 地址:{this.state.info.getIn(['location','province'])} -{this.state.info.getIn(['location','city'])} <br /> {/* List的循环遍历展示 */} 爱好:{this.state.info.get('favor').map((item, index) => { return <li key={item}> {item} <button onClick={() => { console.log(index); // 删除数据(List)使用到updataIn this.setState({ /* 使用updateIn获取数组的第一层数据,第二个参数为回调函数 用于返回修改后的List */ info:this.state.info.updateIn(["favor"],(list)=>list.splice(index,1)) }) }}>删除</button> </li> })} </div> </div> ) } }
|
结果展示:
immutable
结合redux
来使用
- 在
redux
中,修改函数reducer
需要保持纯函数的设计,就是对原状态不改变的情况下,将原装态修改成新状态返回出去,因此在redux
中集合immutable
来使用一般是在reducer
中来使用的,但是需要切记修改后的数据在reducer
中返回是否为immutable
对象,如果是immutable
对象则需要使用get()
来获取数据展示,set()
来修改数据; 如果为普通的对象则直接展示即可。
在reducer
中返回的是immutable
对象
import { fromJS } from "immutable"
const isShowBottomReducer = (prevState=fromJS({// 将源数据改为immutable数据结构 data:'' }),action)=>{ switch(action.type){ case "getData": return prevState.set("show",action.value) default: return prevState } }
export default isShowBottomReducer
state = { isShow:store.getState().isShowBottomReducer.get('show') }
|
在reducer
中返回的是普通对象(toJs()
)[推荐使用
]
import { fromJS } from "immutable"
const isShowBottomReducer = (prevState={ data:'' },action)=>{ let newState = fromJS(prevState) switch(action.type){ case "getData": return newState.set('data',action.value).toJS() default: return prevState } }
export default isShowBottomReducer
state = { isShow:store.getState().isShowBottomReducer.show }
|