2016-06-24 28 views
1

我必須寫mapStateToProps像下面寫`state.tree`,而不是`state.xxxReducer.tree`在`mapStateToProps`(反應終極版)

function mapStateToProps(state, ownProps) { 
    return { 
    node: ownProps.info? state.TreeNodeReducer.tree[ownProps.info.path] : {} 
    }; 
} 

結合減速機:

import { combineReducers } from 'redux'; 
import TreeNodeReducer from './TreeNodeReducer' 

const rootReducer = combineReducers({ 
    TreeNodeReducer 
}); 

export default rootReducer; 

減速器/ TreeNodeReducer.js

import { OPEN_NODE, CLOSE_NODE, GET_NODES } from '../constants/NodeActionTypes'; 

const initialState = { 
    open: false, 
    info: {} 
} 

class NodeModel { 
    constructor(path, type, right) { 
     this.name = path; 
     this.path = path; 
     this.type = type; 
     this.right = right; 
    } 
} 

let lastId = 0; 

function getFileList() { 
    var testNodes = [] 
    for (var i=0; i< 3; i++) { 
    testNodes.push(new NodeModel(lastId,'d', i.toString())) 
    lastId++; 
    } 

    return testNodes 
} 


const getNodes = (state, action) => { 
    var { path } = action 
    var tree = state.tree ? state.tree : {} 
    tree[path] = getFileList(path) 
    return { 
    ...state, 
    tree:tree 
    }; 
}; 

export default function (state = initialState, action) { 
    switch (action.type) { 
    case OPEN_NODE: 
     return { ...getNodes(state, action), open:true }; 
    case GET_NODES: 
     return getNodes(state, action); 
    case CLOSE_NODE: 
     return { 
     ...state, 
     open:false 
     }; 
    default: 
     return state; 
    } 
} 

因爲state.TreeNodeReducer.tree是一個全球性的狀態,它容納所有節點的信息,I W ant通過狀態直接訪問它。通過reducer的狀態返回將按reducer的名稱進行包裝,這對於簡單的項目並不方便。 Office doc不提供這種方式。任何想法?

PS:我不得不說我想繼續使用combineReducers,我看到有些項目不使用它,直接通過reducer存儲可以達到我的目的但不好。

+0

你能否也請顯示TreeNodeReducer? – Ashitaka

+0

@Ashitaka我已經更新了代碼。 – Mithril

回答

2

實現你的願望取決於TreeNodeReducer處理的狀態。

如果減速只是處理tree屬性,像這樣:

function treeNodeReducer(state = initialState, action) { 
    switch (action.type) { 
    case SOME_ACTION: 
     return Object.assign({}, state, { tree: action.tree, ... }) 
    default: 
     return state 
    } 
} 

我要說改變減速消除tree財產,並直接與國家合併,就像這樣:

function treeNodeReducer(state = initialState, action) { 
    switch (action.type) { 
    case SOME_ACTION: 
     return Object.assign({}, state, action.tree) 
    default: 
     return state 
    } 
} 

這樣我們可以通過state.treeNodeReducer訪問mapStateToProps中的樹形對象。

但這仍然不是我們想要的。我們想將treeNodeReducer重命名爲tree。有針對兩種解決方案:

  1. 或者:

    import { combineReducers } from 'redux'; 
    import TreeNodeReducer from './TreeNodeReducer' 
    
    const rootReducer = combineReducers({ 
        tree: TreeNodeReducer 
    }); 
    
    export default rootReducer; 
    
  2. 或者:

    import { combineReducers } from 'redux'; 
    import tree from './TreeNodeReducer' 
    
    const rootReducer = combineReducers({ 
        tree 
    }); 
    
    export default rootReducer; 
    

這樣我們就可以用state.tree訪問mapStateToProps樹對象。

+0

謝謝!由於'treeNodeReducer'不能處理一個動作,並且可以處理2或3個屬性,因此我應該直接將屬性與狀態合併,是嗎?似乎不是一個漂亮的方式,但是唯一的方法。呃...明白,再次感謝。 – Mithril

+0

我知道如果除了由'TreeNodeReducer'處理的'tree'之外還有其他狀態,它就不是很漂亮了。但是如果你看看官方的doc例子,你可以看到reducer直接返回某個狀態,而不是包含該狀態的對象,這是非常正常的。檢查[combineReducers文檔](https://github.com/reactjs/redux/blob/master/docs/api/combineReducers.md)。在那裏,'counter' reducer返回一個數字,'todos'返回一個數組。 – Ashitaka

+1

我建議閱讀[Reducers and Designing the State Shape]上的文檔(http://redux.js.org/docs/basics/Reducers.html)。在那裏,您可以觀察到從單個減速器演變成幾個較小的減速器,每個減速器處理整個狀態的一小部分。例如,最後,'visibilityFilter' reducer返回一個字符串。 – Ashitaka