在使用reactjs和redux开始我的开发之后,我认为在使用redux时使用immutable.js会更好。
但是......也许我迟钝了,或者在正确使用它之前需要一些练习,一切都崩溃了。
如果你能帮助理解这里的错误,那就太棒了!
所以,这是我的第一个代码:
export function posts(state = {
isFetching: true,
didInvalidate: false,
items: []
}, action) {
switch (action.type) {
case INVALIDATE_REQ:
return Object.assign({}, state, {
didInvalidate: true
});
case REQUEST_POSTS:
return Object.assign({}, state, {
isFetching: true,
didInvalidate: false
});
case RECEIVE_POSTS:
return Object.assign({}, state, {
isFetching: false,
didInvalidate: false,
items: action.posts
});
default:
return state;
};
};
我改变了这种方式:
const initPostState = Map({
isFetching: true,
didInvalidate: false,
items: []
});
export function posts(state = initPostState, action) {
switch (action.type) {
case INVALIDATE_REQ:
return state.set('didInvalidate', true);
case REQUEST_POSTS:
return state.set({
isFetching: true,
didInvalidate: false
});
case RECEIVE_POSTS:
return state.set({
isFetching: false,
didInvalidate: false,
items: action.posts
});
default:
return state;
};
};
我的容器MapStateToProps:
function mapStateToProps(state) {
const {
posts: isFetching,
posts
} = state.posts;
console.log(state);
...
问题是,我如何访问我的状态? 国家控制台报告:
我输了!救命啊!
答案 0 :(得分:2)
您需要使用immutableJS中的get
方法
使用state.get('didInvalidate')
访问didInvalidate
的值,与其他值类似。
如果您使用的是javascript对象,则可以像state.get('something').toJS()
那样使用它
这样做可以给你一个想法
function mapStateToProps(state){
const isFetching = state.get('isFetching'),
const items = state.get('items').toJS();
}
答案 1 :(得分:2)
切勿在{{1}}中使用toJS()
。来自Redux文档:
使用
mapStateToProps
将Immutable.JS对象转换为JavaScript对象将每次返回一个新对象。如果在toJS()
中执行此操作,则会使组件在每次状态树更改时都认为对象已更改,因此会触发不必要的重新呈现。
如果您的应用需要高性能,则必须在Dumb组件中使用Immutable.js及其mapSateToProps
和get()
助手。
此外,由于ImmutableJS具有多功能API,因此在大多数情况下它会删除 需要帮助库,如lodash。
但在大多数情况下,您可以使用他们建议的代码,通过牺牲性能来将Immutable.js与您的组件分开。
HOC组件(使用isIterable谓词的最新immutable.js):
getIn()
HOC组件(使用isImmutable谓词的最新immutable.js):
import React from 'react';
import { Iterable } from 'immutable';
export const toJS = (WrappedComponent) =>
(wrappedComponentProps) => {
const KEY = 0;
const VALUE = 1;
const propsJS = Object.entries(wrappedComponentProps)
.reduce((newProps, wrappedComponentProp) => {
newProps[wrappedComponentProp[KEY]] =
Iterable.isIterable(wrappedComponentProp[VALUE])
? wrappedComponentProp[VALUE].toJS()
: wrappedComponentProp[VALUE];
return newProps;
}, {});
return <WrappedComponent {...propsJS} />
};
使用方法:
import React from 'react';
import { isImmutable } from 'immutable';
export const toJS = (WrappedComponent) =>
(wrappedComponentProps) => {
const KEY = 0;
const VALUE = 1;
const propsJS = Object.entries(wrappedComponentProps)
.reduce((newProps, wrappedComponentProp) => {
newProps[wrappedComponentProp[KEY]] =
isImmutable(wrappedComponentProp[VALUE])
? wrappedComponentProp[VALUE].toJS()
: wrappedComponentProp[VALUE];
return newProps;
}, {});
return <WrappedComponent {...propsJS} />
};
在Redux immutable-js-best-practices文档部分中有很多要继续前进的链接。
答案 2 :(得分:1)
如果将ImmutableJS与redux一起使用,那么整个应用程序状态是不可变的。在connect
函数中,使用state.get(&#34; posts&#34;)访问posts
状态。然后,您必须使用get()
来访问posts
州属性。或者您可以使用toJs()来避免在组件内部操纵不可变。