immutable.js笔记

Immutable.js原理分析

Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。

Immutable.js的使用

安装

cnpm i immutable --save

Map的操作

import React from 'react';
import ReactDOM from 'react-dom';
import {Map} from 'immutable';

//声明一个对象,这个对象要设置为不可被修改的对象
const state = {
  value: 'hello',
  list: ['html','css','js']
}

//将要设置不可更改的对象,传入到Map()方法中,会返回一个新的state对象
const imState = Map(state)

//将state对象设置为不可被修改的对象后,使用 get('key') 方法取值
console.log(imState.get('value'))

//使用set()方法修改值,修改后会返回一个新的对象,原来的对象数据没有变化
const newImState = imState.set('value','world')

console.log(imState.get('value'))
console.log(newImState.get('value'))


ReactDOM.render(
  <div>
    hello
  </div>
  ,document.getElementById('root'));

List的操作

import React from 'react';
import ReactDOM from 'react-dom';
import {List} from 'immutable';

//声明一个数据,要将该数组设置为不可更改的数组
const arry = [1,2,3]

//将数组传入 List() 中即可设置不可更改的数组对象
const imList = List(arry)

//对imList做追加操作,不会对原数组做修改,会返回一个新的数组对象
const newImList = imList.push(4)

console.log(imList.size,newImList.size)


ReactDOM.render(
  <div>
    hello
  </div>
  ,document.getElementById('root'));

fromJS的操作

import React from 'react';
import ReactDOM from 'react-dom';
import {fromJS} from 'immutable';

//声明一个不可更改的对象
const state = {
  value: 'hello',
  list: ['html','css','js'],
  obj: {
    x: 1,
    y: {
      z: 2
    }
  }
}

//把state传入的fromJS()中
const imState = fromJS(state)

//获取imState中的值
console.log(imState.get('value'))

//修改imState中的值,修改对象中的第一层属性的值,可以使用 set() 方法
const newState = imState.set('value','world')
console.log(newState.get('value'))

//修改imState中更深层次的数据,需要使用 setIn() 或 updateIn() 方法
//setIn() 可以直接赋值,参数1为对象属性的层级结构,按照层级顺序编写到数组中;参数2为要赋的值
const newState1 = imState.setIn(['obj','y','z'],100)
//updateIn() 可以对原始值做修改后再返回新的值,参数1同上,参数2为修改值时用的回调函数,回调函数的参数为对象原始值
const newState2 = imState.updateIn(['obj','y','z'], val => val + 1)

//获取深层对象结构的值,使用 getIn() 方法
console.log(newState1.getIn(['obj','y','z']))
console.log(newState2.getIn(['obj','y','z']))


ReactDOM.render(
  <div>
    hello
  </div>
  ,document.getElementById('root'));

在redux中使用immutable

使用Map操作

第1步:创建store

import {createStore} from 'redux'
import reducer from './reducer'

const store = createStore(reducer)

export default store

第2步:创建reducer

import {Map} from 'immutable'

//使用Map()来创建原始对象,创建的原始对象为不可更改的对象
const defaultState = Map({
    value: ''
})

const reducer = (state = defaultState, action)=>{

    //在执行修改state的代码中,使用 set() 方法完成修改操作,返回一个新的对象
    if(action.type === 'change_value'){
        return state.set('value',action.value)
    }

    return state
}

export default reducer

第3步:创建App.js文件,用于修改redux中的数据

import React, { Component } from 'react'
import store from './store'
import Son from './Son'

export default class App extends Component {

    constructor() {
        super()
        this.state = store.getState()
        store.subscribe(()=>{
            this.setState(store.getState())
        })
    }

	//文本框输入事件
    handleInput(e){
        let action = {
            type: 'change_value',
            value: e.target.value
        }
        store.dispatch(action)
    }

    render() {
        return (
            <div>
                <input value={this.state.value} onChange={this.handleInput.bind(this)}></input>
                <Son></Son>
            </div>
        )
    }
}

第4步:创建Son.js用于实时显示redux中的数据

import React, { Component } from 'react'
import store from './store'

export default class Son extends Component {

    constructor(){
        super()

        //此时使用store.getState()获取的数据为immutable处理后的对象,要使用get()方法获取具体值
        this.state = {
            value:  store.getState().get('value')
        }

        store.subscribe(()=>{
            this.setState({
                value: store.getState().get('value')
            })
        })
    }

    render() {
        return (
            <div>
                Son组件:{this.state.value}
            </div>
        )
    }
}

使用fromJS操作

App.js代码

import React, { Component } from 'react'
import store from './store'
import Son from './Son'

export default class App extends Component {


    constructor() {
        super()

        this.state = {
            value: '',
            name: '',
            age: 0,
            h1: ''
        }
    }

    //提交事件
    handleSubmit(){
        let action = {
            type: 'reg_user',
            value: this.state.value,
            name: this.state.name,
            age: this.state.age,
            h1: this.state.h1
        }
        store.dispatch(action)
    }


    render() {

        return (
            <div>
                <div>
                    普通值:<input value={this.state.value} onChange={(e)=>{
                        this.setState({value: e.target.value})
                    }}></input>
                </div>

                <div>
                    姓名:<input value={this.state.name} onChange={(e)=>{
                        this.setState({
                            name: e.target.value
                        })
                    }}></input>
                </div>

                <div>
                    年龄:<input value={this.state.age} onChange={(e)=>{
                        this.setState({
                            age: e.target.value
                        })
                    }}></input>
                </div>

                <div>
                    爱好:<input value={this.state.h1} onChange={(e)=>{
                        this.setState({
                            h1: e.target.value
                        })
                    }}></input>
                </div>

                <button onClick={this.handleSubmit.bind(this)}>提交</button>
                
                
                <hr />
                
                <Son></Son>
            </div>
        )
    }
}

store.js代码

import {createStore} from 'redux'
import reducer from './reducer'

const store = createStore(reducer)

export default store

reducer.js代码

import {fromJS} from 'immutable'

//使用Map()来创建原始对象,创建的原始对象为不可更改的对象
const defaultState = fromJS({
    value: '',
    user: {
        name: '',
        age: 0,
        hobby: {
            h1: ''
        }
    }
})

const reducer = (state = defaultState, action)=>{

    //使用fromJS中的 setIn() 方法修改数据
    if(action.type === 'reg_user'){

        return  state.setIn(['user','name'],action.name)
      .setIn(['user','age'],action.age)
      .setIn(['user','hobby','h1'],action.h1)
      .set('value',action.value)
    }

    return state
}

export default reducer

Son.js代码

import React, { Component } from 'react'
import store from './store'

export default class Son extends Component {

    constructor(){
        super()

        //此时store.getState()获取到数据为复杂类型,要使用getIn()方法
        const storeState = store.getState();
        this.state = {
            value:  storeState.get('value'),
            user: {
                name: storeState.getIn(['user','name']),
                age: storeState.getIn(['user','age']),
                hobby: {
                    h1: storeState.getIn(['user','hobby','h1'])
                }
            }
        }

        //监听store中的数据更新
        store.subscribe(()=>{
            const storeState2 = store.getState();
            this.setState({
                value:  storeState2.get('value'),
                user: {
                    name: storeState2.getIn(['user','name']),
                    age: storeState2.getIn(['user','age']),
                    hobby: {
                        h1: storeState2.getIn(['user','hobby','h1'])
                    }
                }
            })
        })
    }

    render() {
        let {value,user} = this.state
        return (
            <div>
                Son组件:{value}
                <p>姓名:{user.name}</p>
                <p>年龄:{user.age}</p>
                <p>爱好:{user.hobby.h1}</p>
            </div>
        )
    }
}
Immutable.js是一个JavaScript库,用于创建不可变的数据结构。它提供了一组用于创建、操作和查询这些数据结构的API。以下是使用Immutable.js的一些常见步骤: 1. 安装Immutable.js 可以使用npm或yarn安装Immutable.js: ```bash npm install immutable ``` ```bash yarn add immutable ``` 2. 导入Immutable.js 在需要使用Immutable.js的文件中,导入Immutable.js的核心模块: ```js import Immutable from 'immutable'; ``` 3. 创建不可变的数据结构 使用Immutable.js的函数来创建不可变的数据结构,例如: ```js const data = Immutable.fromJS({ foo: { bar: 1 } }); ``` 这将创建一个不可变的Map对象,其中包含一个名为`foo`的键,它的值是包含一个`bar`键和值为1的对象。 4. 操作不可变的数据结构 使用Immutable.js的方法来对不可变数据结构进行操作,例如: ```js const newData = data.setIn(['foo', 'bar'], 2); ``` 这将返回一个新的Immutable对象,其中`foo.bar`的值已经被更新为2。需要注意的是,原始的数据结构并没有被修改,而是返回了一个新的对象来代表更新后的值。 5. 查询不可变的数据结构 使用Immutable.js的方法来查询不可变数据结构,例如: ```js const value = data.getIn(['foo', 'bar']); ``` 这将返回`foo.bar`的值,即1。 以上就是使用Immutable.js的基本步骤。需要注意的是,由于Immutable.js创建的数据结构是不可变的,因此在对其进行操作时需要使用Immutable.js提供的方法,而不是原生的JavaScript方法。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值