2016-08-04 47 views
2

我有一個ReactJs應用程序,它使用Redux來管理其商店。我的狀態是一個複雜的json,其文件可以改變。當我啓動reducer時,我必須指定初始狀態,否則在從服務器獲取內容之前訪問它時,會出現'undefined'錯誤。以下是例子,初始狀態未定義在REDX連接的反應應用程序

//Test.jsx 
 
class Test extends React.Component{ 
 
    componentWillMount(){ 
 
     fetchContent({ 
 
     type: SET_CONTENT 
 
     }); 
 
    } 
 
    render(){ 
 
     return(
 
     <div> {this.props.header} </div> 
 
    ) 
 
    } 
 
    mapStateToProps(state){ 
 
     return{ 
 
     header: state.reducer1.a.b.c 
 
     } 
 
    } 
 
} 
 
export default (mapStateToProps)(Test); 
 

 

 
//reducer1.js 
 
export default function reducer1(state = {}, action = {}) { 
 
    switch (action.type) { 
 
    case SET_CONTENT: 
 
     return Object.assign({}, action.data); 
 
    default: 
 
     return state; 
 
    } 
 
} 
 
    
 
//reducer2.js 
 
export default function reducer2(state = {}, action = {}) { 
 
    switch (action.type) { 
 
    case SET_SOMETHING_ELSE: 
 
     return Object.assign({}, action.data); 
 
    default: 
 
     return state; 
 
    } 
 
} 
 
    
 
//CombinedReducer.js 
 
export default combinedReducers(Object.assign({}, {reducer1}, {reducer2}))

現在,當首次組件初始化,state.reducer1.a.b.c因爲fetchContent()犯規似乎在這一點上被稱爲拋出不確定的。

所以我的問題是我如何解決這個問題?在reducer中指定初始狀態是唯一的選擇嗎?像下面,

//reducer1.js 
 
export default function reducer1(state = { a: { b: { c: "somedata"}}}, action = {}) { 
 
    switch (action.type) { 
 
    case SET_CONTENT: 
 
     return Object.assign({}, action.data); 
 
    default: 
 
     return state; 
 
    } 
 
}

回答

0

可以做到這一點,但你也可以只更新您的mapState函數來檢查第一個關鍵的存在。

function mapStateToProps(state){ 
    return{ 
    header: state.reducer1.a ? state.reducer1.a.b.c : <div>Loading..</div> 
    } 
} 

此外,我假定你的意思有mapStateToProps外的類定義的,因爲它是你傳遞給connect,而不是特定於組件的功能:

class C { 
    ... 
} 

function mapStateToProps (state) {} 

connect(mapStateToProps)(C) 

最後,您缺少派遣你的fetchContent電話?這是使用redux-thunk嗎?

+0

所以唯一可能的解決方案如果任lnitialize狀態像我一樣還是從國家的數據訪問每個級別做null檢查! 是的,功能應該是在外面。因爲我很快就寫下了這個,所以沒有仔細研究。是的,fetchContent是我內部調用dispatch的動作創建器上的一個函數。 – user3807940

+0

我不確定你的期望是什麼,有些事情爲你做空檢查?你真的只有兩個狀態來檢查a)predata和b)數據。這只是一個空檢查,而不是'每個數據訪問級別' – azium

0

在大多數情況下,您不應將所有響應數據存儲在減速器中。您的狀態層次結構不應該重複JSON響應的層次結構。

這會我更簡單,只存儲c變量在減速:

//reducer1.js 

export default function reducer1(state = { c: undefined }, action) { 
    switch (action.type) { 
    case SET_CONTENT: 
     return Object.assign({}, state, { c: action.data.a.b.c }); 
    default: 
     return state; 
    } 
} 

此外,你必須在你的代碼中的錯誤:

  • mapStateToProps功能應該
  • 類之外定義
  • 而不是直接調用fetchContent函數,您應該將它傳遞給調度。
// Test.jsx 

class Test extends React.Component{ 
    componentWillMount(){ 
    dispatch(fetchContent({ 
     type: SET_CONTENT 
    })); 
    } 

    render() { 
    const { header } = this.props; 
    return header ? (
     <div>{header}</div> 
    ) : (
     <div>Loading...</div> 
    ); 
    } 
} 

function mapStateToProps(state) { 
    return { 
    header: state.reducer1.c 
    } 
} 

export default (mapStateToProps)(Test); 
+0

這是否意味着redux-store只能存儲一個簡單的json?即使服務器的響應是複雜的,深度嵌套的json,我應該將它們轉換成簡單的1級json,然後再將它們存儲到redux-store中? 此外,關於代碼錯誤,這是一個打字錯誤:)我的意思是在類定義之外有mapStateToProps,而我的fetchContent是我的一個動作創建器中的一個函數,它在內部使用調度:) – user3807940

+0

@ user3807940,這取決於情況。如果您從服務器獲得深度嵌套的json,請考慮使用'normalizr'包。它用於將深嵌套的json轉換爲1級數據。 – 1ven

+0

很酷,以前聽說過normalizr,但從未嘗試過。那就給它留言吧!感謝您的回覆:) – user3807940

相關問題