我想尝试练习如何使用immutable.js
但我不知道如何编辑我的减速机到不可变的方式。 (我试着在github上找到一些代码,但它们是基本的)
我的组件也有错误
所以我想请求帮助,告诉我如何重构我的减速机?
这是我原来的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_STATE
fromJS()
** immutable 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 (...)
});
答案 0 :(得分:0)
我在我的代码中使用了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);
答案 1 :(得分:0)
你不能用点表示法引用object属性,因为它是一个Immutablejs Map(当你将状态对象传递给fromJS Immutablejs函数时,你在reducer中创建了Map)来使用你需要使用的Map上的函数map Immutablejs api返回一个新框而不是对旧框的引用。
首先使用getIn函数,该函数将返回一个新框而不是对旧框的引用。
根据你通过道具传递状态的方式,我无法给你一个明确的答案,我很困惑editZone属性的来源,因为我只能在你的初始状态下看到它只是一个函数名,是吗?切片状态并从函数名称创建属性?但无论如何你可以尝试一下
变化:
const boxes = this.props.editZone.box; const playgroundObjetcs = boxes.map(box =&gt; {return(...)});
要:
const playgroundObjects = this.props.getIn(['editZone','box'])。map(box =&gt; {return(...)});
或者尝试:
const boxes = this.props.editZone.box.toJS() playgroundObjetcs = boxes.map(box =&gt; {return(...)});
希望现在对于发生的事情有意义。