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;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值