REACT-immutable不可变对象
1. 概述
每次修改一个 Immutable 对象时都会创建一个新的不可变的对象,在新对象上操作并不会影响到原对象的数据。实现深拷贝。
GitHub-immutable-js
npm i immutable
2. 使用
2.1 base.js
用JSON中的api进行深拷贝,但是属性值为undefined时会报错
let obj1 = {
a:1
}
let obj2 = JSON.parse(JSON.stringify(obj1));
obj2.a = 2;
console.log(obj1,obj2)
//{a: 1} {a: 2}
2.2 Map-obj
import React, { Component } from 'react'
import {Map} from 'immutable'
export default class App extends Component {
state = {
info1:Map({
name:'xxx',
age:10,
}),
info2:{
name:'xxx',
age:10,
},
}
render() {
return (
<div>
<button onClick={()=>{
this.setState({
info1:this.state.info1.set('name','lala').set('age',18)
})
}}>bnt1</button>
{this.state.info1.get('name')} - {this.state.info1.get('age')}
<button onClick={()=>{
let immu = Map(this.state.info2);
let newImmu = immu.set('name','lala').set('age',18);
this.setState({
info2:newImmu.toJS()
});
}}>bnt2</button>
{this.state.info2.name} - {this.state.info2.age}
</div>
)
}
}
2.3 Map-组件更新
控制子组件的更新
import React, { Component } from 'react'
import {Map} from 'immutable'
export default class App extends Component {
state = {
info:Map({
name:'kkk',
select:'aa',
filter:Map({
text:'llll',
up:true
})
})
}
render() {
return (
<div>
<button onClick={()=>{
this.setState({
info:this.state.info.set('name','lala')
})
}}>bnt1</button>
{this.state.info.get('name')}
<Child filter={this.state.info.get('filter')}/>
</div>
)
}
}
class Child extends Component {
componentDidUpdate(){
console.log('child-componentDidUpdate')
}
shouldComponentUpdate(nextProps,nextState){
if(this.props.filter === nextProps.filter){
return false
};
return true
}
render() {
return (
<div>
Child
</div>
)
}
}
2.4 List-array
import React, { Component } from 'react'
import {List} from 'immutable'
let arr1 = List([1,2,3]);
let arr2 = arr1.push(4);
let arr3 = arr2.splice(0,1);
console.log(arr1.toJS(),arr2.toJS(),arr3.toJS())
export default class App extends Component {
state = {
favor:List(['aa','bb','cc'])
}
render() {
return (
<div>
{
this.state.favor.map(item=>{
return <div key={item}>{item}</div>
})
}
</div>
)
}
}
2.5 Map-List
import React, { Component } from 'react'
import {Map,List} from 'immutable'
export default class App extends Component {
state = {
info:Map({
name:'qqq',
location:Map({
province:'浙江',
city:'温州'
}),
favor:List(['aa','bb','cc'])
})
}
render() {
return (
<div>
<h1>个人信息修改</h1>
<button onClick={()=>{
this.setState({
info:this.state.info.set('name','llll')
.set('location',this.state.info.get('location').set('city','ccc'))
})
}}>修改</button>
<div>
{this.state.info.get('name')}
<br/>
{this.state.info.get('location').get('province')}
-
{this.state.info.get('location').get('city')}
</div>
{
this.state.info.get('favor').map((item,index)=>{
return (
<div key={item}>
{item}
<button onClick={()=>{
this.setState({
info:this.state.info.set('favor',this.state.info.get('favor').splice(index,1))
})
}}>del</button>
</div>
)
})
}
</div>
)
}
}
2.6 fromJS
import React, { Component } from 'react'
import {fromJS} from 'immutable'
export default class App extends Component {
state = {
info:fromJS({
name:'qqq',
location:{
province:'浙江',
city:'温州'
},
favor:['aa','bb','cc']
})
}
render() {
return (
<div>
<h1>个人信息修改</h1>
<button onClick={()=>{
this.setState({
info:this.state.info.set('name','llll')
.setIn(['location','city'],'ccc')
})
}}>修改</button>
<div>
{this.state.info.get('name')}
<br/>
{this.state.info.getIn(['location','province'])}
-
{this.state.info.getIn(['location','city'])}
</div>
{
this.state.info.get('favor').map((item,index)=>{
return (
<div key={item}>
{item}
<button onClick={()=>{
// this.setState({
// info:this.state.info.setIn(['favor',index],111)
// })
this.setState({
info:this.state.info.updateIn(['favor'],list=>list.splice(index,1))
})
}}>del</button>
</div>
)
})
}
</div>
)
}
}
2.7 应用于redux状态管理
2.7.1 应用1
import {fromJS} from 'immutable'
// 定义一个状态
let initialState = {
show: true
};
// 利用reducer将store和action串联起来
function reducer(prevState = fromJS(initialState), action) {
switch (action.type) {
case 'hidden-tabbar':
return prevState.set('show',false);
case 'show-tabbar':
return prevState.set('show',true);
default:
return prevState;
}
}
export default reducer;
import React, { Component } from 'react'
import IndexRouter from './router/IndexRouter'
import Tabbar from './components/Tabbar'
import './css/App.css'
import store from './redux/store'
// console.log(store)
export default class App extends Component {
state = {
isShow:store.getState().TabbarReducer.get('show')
}
componentDidMount(){
store.subscribe(()=>{
// console.log('app中订阅',store.getState())
this.setState({isShow:store.getState().TabbarReducer.get('show')})
})
}
render() {
return (
<div>
<div>
<IndexRouter>
{this.state.isShow && <Tabbar />}
</IndexRouter>
</div>
</div>
)
}
}
2.7.2 应用2
import {fromJS} from 'immutable'
const initialState = {
cityName:'北京'
}
const reducer = (prevState = initialState,action) => {
let newState = fromJS(prevState);
switch(action.type){
case 'change-city':
return newState.set('cityName', action.cityName).toJS();
default:
return prevState
}
}
export default reducer;