【immutable 学习记录】 immutable 和 React 、Redux 结合使用


什么是immutable

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

其中有 3 种最重要的数据结构:

Map:键值对集合,对应于 Object,ES6 也有专门的 Map 对象
List:有序可重复的列表,对应于 Array
Set:无序且不可重复的列表

immutable 和 React、Redux 结合

使用步骤

1. 安装并引入 redux-immutable
   安装: npm i redux-immutable -save  
          yarn add redux-immutable -s
    引入:
    import {combineReducers} from 'redux-immutable'
2. 初始化reducer
const rootReducer = combineReducers({
    cart
})
// state 必须是 immutable 类型
function cart (state, action){
    ...
}
3. mapStateToProps 的 state 也是 immutable 类型,使用时应该使用 get 方法

详细代码

App.js 中的代码如下:

import React, { Component } from 'react';
import './App.css';
import CartInfo from './CartInfo';
import InputBar from './InputBar';

class App extends Component {
  render(){
    return (
    <div className="App">
     <InputBar />
     <hr /> 
     <CartInfo />
    </div>
  );
  }
}

export default App;

CartInfo.js 中的代码如下:

import React, { Component } from 'react'
import { is } from 'immutable'
import { connect } from 'react-redux'

class CartInfo extends Component {
    shouldComponentUpdate(nextProps) {
        // 如果下一个 props 与当前的 props 不相等时再刷新
        // return !nextProps.cart.equals(this.props.cart)
        return !is(nextProps.cart, this.props.cart)
    }
    render() {
        const lis = []
        // console.log('保存成功')
        // immutable 类型的数据循环时使用 forEach
        this.props.cart.forEach((v, k) => {
            lis.push(
                <li key={k}>商品名:{k} 数量:{v}</li>
            )
        });
      
        return (
            <ul>
                {lis}
            </ul>
        )
    }
}
// 接收 参数 cart
const mapStateToProps = (state) =>({
    cart: state.get('cart')
})
// 加强组件 CartInfo,通过 mapStateToProps 接收到传递进来的参数
export default connect (mapStateToProps)(CartInfo)

InputBar.js 中的代码如下:

import React, { Component } from 'react'
import { connect } from 'react-redux'

 class InputBar extends Component {
     save = () =>{
         const goods_name = this.refs.goods_name.value
         const count = this.refs.count.value
         this.props.saveToCart({
             goods_name,
             count
         })
     }
    render() {
        return (
            <div>
                商品:<input type='text' ref='goods_name'></input><br></br>
                数量:<input type='number' ref='count'></input><br></br>
                <button onClick={this.save}>保存</button>
            </div>
        )
    }
}
// 传递参数,通过 action 的类型,判断此时要进行什么样的操作,将数据处理后以json的形式传递出去
const mapDispatchToProps = (dispatch) =>({
    saveToCart : function(json){
        dispatch({
            type: 'SAVE_TO_CART',
            payload: json
        })
    }
})
// 加强组件 InputBar,通过 mapDispatchToProps 将处理后的数据发送出去
export default connect(null, mapDispatchToProps)(InputBar)

index.js 中的代码如下:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { combineReducers } from 'redux-immutable'
import { legacy_createStore as createStore} from 'redux'
import { Map } from 'immutable'
import { Provider} from 'react-redux'

const cart = (state = Map({}), action) => {
  // 传入的类型须是immutable类型,state 必须初始化
  switch (action.type) {
    case 'SAVE_TO_CART':
      return state.set(action.payload.goods_name, action.payload.count)

    default:
     return state
  }
}
const reducers = combineReducers({
  cart
})

const store = createStore(reducers)

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>

  </React.StrictMode>
);

store.subscribe(() => {
  root.render(
    <React.StrictMode>
      <Provider store={store}>
        <App />
      </Provider>

    </React.StrictMode>
  );
})


运行结果

页面展示

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值