【问题标题】:How to convert redux with immutable.js如何使用 immutable.js 转换 redux
【发布时间】:2016-09-28 10:05:18
【问题描述】:

我想尝试练习如何使用immutable.js
但我不知道如何将我的减速器编辑为不可变的方式。 (我尝试在 github 上找到一些代码,但它们是基本的)
而且我的组件也有错误。
所以我想寻求帮助来指导我如何重构我的reducer?

这是我原来的 reducer.js

原始 reducer.js

import * as TYPE from '../constants/ActionTypes';

const INIT_STATE = {
  box: [
    { 'id': 1,
      'axisX': 10,
      'axisY': 10,
      'width': 200,
      'height': 200,
    },
    { 'id': 2,
      'axisX': 20,
      'axisY': 300,
      'width': 200,
      'height': 200,
    }
    ]
};


export default function editZone(state = INIT_STATE, action) {
  let newState = null;
  switch (action.type) {
    case TYPE.UPDATE_POSITION:
      newState = Object.assign({}, state);
      newState.box = newState.box.map(box => {
        if (box.id === action.payload.id) {
          box.axisX = action.payload.x;
          box.axisY = action.payload.y;
        }
        return box;
      });
      return newState;
    default:
      return state;
  }
}

我将其编辑为使用immutable.js,我只是将INIT_STATEfromJS() 相加

**不可变的reducer.js **

import {List, Map, fromJS} from 'immutable'; 

const INIT_STATE = fromJS({
      box: [
        { 'id': 1,
          'axisX': 10,
          'axisY': 10,
          'width': 200,
          'height': 200,
        },
        { 'id': 2,
          'axisX': 20,
          'axisY': 300,
          'width': 200,
          'height': 200,
        }
        ]
    });

我面临一个错误:TypeError: Cannot read property 'map' of undefined
我尝试控制台输出this.props.editZone
它显示Map {size: 2, _root: ArrayMapNode, __ownerID: undefined, __hash: undefined, __altered: false}
我怎样才能解决这个问题??

boxComponent.js

const boxes = this.props.editZone.box;
const playgroundObjetcs = boxes.map(box => { 
    return (...)
});

【问题讨论】:

  • 首先在 reducer 中使用 state.get('box') 来获取 state 的 box 属性,然后你可以在该数组上使用 map。

标签: reactjs redux immutable.js


【解决方案1】:

我在我的代码中使用 Immutable.js。

希望这对你有帮助。

减速器

import Immutable from 'immutable';
import actionConsts from 'constants/actions';

const initialState = Immutable.fromJS({
    isUserLoggedIn: false
});

const user = (state = initialState, action = {}) => {
    switch (action.type) {
        case actionConsts.get('RECEIVE_INIT_DATA'):
            return state.merge(Immutable.fromJS(action.payload.user));
        default:
            return state;
    }
};

export default user;

容器

import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import Base from 'components/base';
import 'styles/app.sass';
import { fetchAppBaseData } from 'actions/init';
import { clearErrorAction } from 'actions/error';

class BaseContainer extends React.Component {

    render() {
        return (
            <Base {...this.props} />
        );
    }
}

BaseContainer.propTypes = {
    skin: PropTypes.object.isRequired,
    sim: PropTypes.object.isRequired,
    user: PropTypes.object.isRequired,
    children: PropTypes.object.isRequired,
    fetchAppBase: PropTypes.func.isRequired,
    clearError: PropTypes.func.isRequired
};
BaseContainer.defaultProps = {
    skin: {},
    user: {},
    sim: {}
};

const mapStateToProps = (state) => ({ ...(state.toJS()) });

const mapDispatchToProps = (dispatch) => ({
    fetchAppBase() {
        dispatch(fetchAppBaseData());
    },

    clearError() {
        dispatch(clearErrorAction());
    }
});

export default connect(mapStateToProps, mapDispatchToProps)(BaseContainer);

【讨论】:

  • 答案如何?
【解决方案2】:

您不能使用点符号引用对象属性,因为它是一个 Immutablejs Map(当您将状态对象传递给 fromJS Immutablejs 函数时,您在 reducer 中创建了 Map)以在您需要使用的 Map 上使用函数映射Immutablejs api 返回一个新框而不是对旧框的引用。

首先使用 getIn 函数,它将返回一个新盒子而不是对旧盒子的引用。

根据你如何通过道具传递你的状态,我无法给你一个明确的答案,我很困惑 editZone 属性来自哪里,因为我不能在你的初始状态中看到它只是一个函数名,你是切片您的状态并从函数名称创建属性?但无论如何你可以尝试一些类似的东西

变化:

常量框 = this.props.editZone.box; const playgroundObjetcs = box.map(box => { return (...) });

收件人:

const playgroundObjects = this.props.getIn(['editZone', 'box']).map(box => { return (...) });

或者尝试:

常量框 = this.props.editZone.box.toJS() playgroundObjetcs = box.map(box => { return (...) });

希望现在这对正在发生的事情有意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    • 2018-04-18
    • 1970-01-01
    • 2016-10-30
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多