2016-07-31 67 views
1

Im新的React和Redux,仍然有點混淆。TypeError:無法讀取react-redux中未定義的屬性'map'

我的目標是使用GET請求在HTML中呈現一堆json數據。我正在使用react和redux來管理對象的狀態,但我相信我的問題是數據甚至不存在

所以基本上每當有人請求URL /課程時,他/她都會看到一堆數據在json中。

我得到錯誤的組件

TypeError: Cannot read property 'map' of undefined

下面的代碼

行動

export function getCourses() { 
    return (dispatch) => { 

    return fetch('/courses', { 
     method: 'get', 
     headers: { 'Content-Type', 'application/json' }, 
    }).then((response) => { 
     if (response.ok) { 
     return response.json().then((json) => { 
      dispatch({ 
      type: 'GET_COURSES', 
      courses: json.courses 
      }); 
     }) 
     } 
    }); 
    } 
} 

減速

export default function course(state={}, action) { 

    switch (action.type) { 
    case 'GET_COURSES': 
     return Object.assign({}, state, { 
     courses: action.courses 
     }) 
    default: 
     return state; 
    } 


} 

組件

import React from 'react'; 
import { Link } from 'react-router'; 
import { connect } from 'react-redux'; 


class Course extends React.Component { 



    allCourses() { 
    return this.props.courses.map((course) => { 
     return(
     <li>{ course.name }</li> 
    ); 

    }); 
    } 

    render() { 
    return (
     <div> 
     <ul> 
      { this.allCourses() } 
     </ul> 

     </div> 
    ) 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
    courses: state.courses 
    } 
} 

export default connect(mapStateToProps)(Course); 

指數減速,在這裏我結合一切

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

export default combineReducers({ 
    course, 
}); 

配置商店,在那裏我存儲INTIAL狀態和減速

import { applyMiddleware, compose, createStore } from 'redux'; 
import thunk from 'redux-thunk'; 
import rootReducer from '../reducers'; 

export default function configureStore(initialState) { 
    const store = createStore(
    rootReducer, 
    initialState, 
    compose(
     applyMiddleware(thunk), 
     typeof window == 'object' && typeof window.devToolsExtension !== 'undefined' ? window.devToolsExtension() : f => f 
    ) 
); 

    return store; 
} 

我相信爲什麼數據不存在,因爲我沒有打電話給行動?任何幫助,將不勝感激。

+0

那是你唯一的減速?還是你在其他地方把減速器結合起來?你能告訴我們你在哪裏初始化商店? –

回答

2

mapStateToProps一個condtion需要根狀態參數(索引減速,這也是根減速),而不是你course減速機。至於我可以告訴大家,這是你的店的結構:

-index <- This is the root reducer 
    -course 

因此,要獲得來自國家課程中,您的組件:

// state is the state of the root reducer 
const mapStateToProps = (state) => { 
    return { 
    courses: state.course.courses 
    } 
} 

此外,你可能會考慮在初始化的狀態course reducer具有一個空的數組課程,所以如果你必須在動作被觸發前渲染組件,你將不會得到錯誤。

const initialState = { 
    courses: [] 
}; 

export default function course(state= initialState, action) { 

    ... 

} 

最後,你不是射擊動作可言,所以你永遠不會真正得到了課程,我想你想一旦Course組件加載它們進行檢索,對於您可以使用componentDidMount事件在你的組件中。

首先,你需要動作映射到組件

// Make sure you import the action 
import { getCourses } from './pathToAction'; 

... 

const mapDispatchToProps = (dispatch) => { 
    return { 
    onGetCourses:() => dispatch(getCourses()) 
    }; 
} 

// Connect also with the dispatcher 
export default connect(masStateToProps, mapDispatchToProps)(Course); 

的屬性現在稱之爲onGetCourses屬性時組件安裝

class Course extends React.Component { 

    componentDidMount() { 
     this.props.onGetCourses(); 
    } 

    ... 

} 
+0

我已經編輯了額外信息的問題。課程絕對是一個陣列。我已經測試過了,它返回一個對象數組。 – sinusGob

+0

但由於某種原因,我的問題是減速器或行動沒有發射一切 – sinusGob

+0

@sinusGob感謝您分享代碼的其餘部分!我編輯了我的答案,在組件中出現錯誤。 –

1

其因爲道具有時可以是不確定的,所以你必須寫這樣

allCourses() { 
    if(this.props.courses){ 
    return this.props.courses.map((course) => { 
     return(
     <li>{ course.name }</li> 
    ); 
    }); 
    } 
    else { 
    return []; 
    } 
+0

道具是未定義的。是因爲我的行動沒有解僱嗎? – sinusGob

+0

是的,可以這樣,你可以使用redux devtools擴展來檢查你的動作是否被觸發,你也應該通過初始狀態來檢查道具是否充滿數據。 – abhirathore2006

相關問題