2016-05-23 22 views
2

在用reactjs和redux开始我的开发之后,我想在使用redux时使用immutable.js会更好。Redux和不可变的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

我迷路了!帮帮我!

回答

2

您需要使用从immutableJS

使用state.get('didInvalidate')get方法来访问的didInvalidate的价值,同样,对于其它值。

如果您使用的是JavaScript对象,那么你就可以得到它像state.get('something').toJS()

这样做应该给你的想法

function mapStateToProps(state){ 
    const isFetching = state.get('isFetching'), 
    const items = state.get('items').toJS(); 
} 
+0

非常感谢!它“工作”,除了我有这个错误: 'state.set'不是一个函数,从这些行: 'return state.set({...'你有什么想法? –

+0

Nevermind,as我所有的状态都没有使用不可变但我认为它在呈现页面时失去了它的Map状态 –

1

如果您使用ImmutableJS和redux,那么您的整个应用程序状态是不可变的。在connect函数中,使用state.get(“posts”)来访问posts状态。那么你将不得不使用get()来访问posts状态属性。或者你可以使用toJs()来避免在你的组件内操纵不可变。

1

切勿mapStateToProps使用toJS()。从终极版文档:

Converting an Immutable.JS object to a JavaScript object using toJS() will return a new object every time. If you do this in mapSateToProps , you will cause the component to believe that the object has changed every time the state tree changes, and so trigger an unnecessary re-render.

如果你的应用需要高性能,你有你的阿呆组件使用Immutable.js他们get()getIn()帮手。

Also since ImmutableJS has versatile API, in most cases it removes the need for helper libraries like lodash.

但是,大多数情况下,您可以使用他们提出的代码通过牺牲性能来将Immutable.js与组件分离。

甲HOC组分(使用所述isIterable谓词最新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} /> 
    }; 

甲HOC组分(与最新的不可变的。JS使用isImmutable谓语):

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} /> 
    }; 

如何使用:

import { connect } from 'react-redux'; 

import { toJS } from './to-js'; 

import DumbComponent from './dumb.component'; 

const mapStateToProps = (state) => { 
    return { 
     /** 
     obj is an Immutable object in Smart Component, but it’s converted to a plain 
     JavaScript object by toJS, and so passed to DumbComponent as a pure JavaScript 
     object. Because it’s still an Immutable.JS object here in mapStateToProps, though, 
     there is no issue with errant re-renderings. 
     */ 
     obj: getImmutableObjectFromStateTree(state) 
    } 
}; 

export default connect(mapStateToProps)(toJS(DumbComponent)); 

有很多的链接,在终极版immutable-js-best-practices文档部分继续前行。

+0

哇谢谢你对这个惊人的解释iogane! –

+0

问题..什么是双星号? 'const ** VALUE = 1;' –

+1

@HusseinDuvigneau感谢您的审查。这不应该在这里,除此之外,我发现他们的整个例子不工作在最后的版本。 – theodor

相关问题