Redux和immutable js,在尝试使用immutable之后我失去了我的状态

时间:2016-05-23 15:01:55

标签: javascript reactjs redux immutable.js

在使用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);
 ...

问题是,我如何访问我的状态? 国家控制台报告:

enter image description here

我输了!救命啊!

3 个答案:

答案 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及其mapSateToPropsget()助手。

  

此外,由于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()来避免在组件内部操纵不可变。