質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

1287閲覧

React Redux Cannot read property 'map' of undefinedのエラー

Y-A-A

総合スコア11

Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2018/05/14 13:13

React,Reduxでリスト中の項目をクリックすると詳細が表示される、という仕組みを作りたいです。
リストを表示するRecipesというコンポーネントを作ったのですが、コンポーネント内で「TypeError: Cannot read property 'map' of undefined」のエラーが出てしまいます。
RecipeListが上手く読み込めていないのかと思いますが、reducersからcomponentsのどこで受け渡しに失敗しているのかわかりません。

どのように修正したら良いのかアドバイスをお願いいたします。
可能であれば、このような時にどの段階で(reducer、container、componentsのどこで)要素の受け渡しに失敗しているのか、確認する方法も合わせて教えていただけますと幸いです。

よろしくおねがいします。

index.js

import React from 'react'; import ReactDOM from 'react-dom'; import {Provider} from 'react-redux'; import {createStore} from 'redux'; import registerServiceWorker from './registerServiceWorker'; import App from './components/App'; import rootReducer from './reducers'; const store = createStore(rootReducer); ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );

reducers/RecipesReducers.js

const RecipesReducer = () => { return [ {title: '白米', image: '', author: '白米さん', comment: '白くてピカピカ'}, {title: '卵焼き', image: '', author: '卵さん', comment: 'しっとりふわふわ'}, {title: '味噌汁', image: '', author: '味噌汁さん', comment: '温かくて身体にしみる!'} ] } export default RecipesReducer;

containers/RecipeList.js

import {connect} from 'react-redux'; import Recipes from '../components/Recipes'; const mapStateToProps = state => { return{ recipeList: state.recipesReducer }; } export default connect (mapStateToProps, null)(Recipes);

components/Recipes.js

import React from 'react'; const Recipes = ({RecipeList}) => { //↓この行でエラーが出ます const list = RecipeList.map(recipe => { return( <li key = {recipe.title} > {recipe.title} </li> ); }); return <ul>{list}</ul> } export default Recipes;

components/App.js

import React from 'react'; import {Component} from 'react'; import Recipes from '../containers/RecipeList' import RecipeDetail from '../containers/RecipeDetail' const App = () => { return ( <div> <Recipes /> <RecipeDetail /> </div> ); }; export default App;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

const mapStateToProps = state => { return{ recipeList: state.recipesReducer }; }

としているので、

const Recipes = ({RecipeList}) => { //↓この行でエラーが出ます const list = RecipeList.map(recipe => {

は、

const Recipes = ({ recipeList }) => { //↓この行でエラーが出ます const list = recipeList.map(recipe => {

の間違いではないでしょうか。

もしかすると他の部分に原因があるかもしれませんが、
その場合は掲載されていない他のファイルのコードも全て載せてみてください。

import rootReducer from './reducers';

特に、この読み込んでいるファイルなどですね。

可能であれば、このような時にどの段階で(reducer、container、componentsのどこで)要素の受け渡しに失敗しているのか、確認する方法も合わせて教えていただけますと幸いです。

今回のエラーはTypeError: Cannot read property 'map' of undefinedなので、Recipesコンポーネントのpropsに渡ってくることを期待しているRecipeListundefinedであることが分かります。

なので、Recipesコンポーネントの前のどこかに原因があると言えます。

const mapStateToProps = state => { //確認 console.log(state); return{ recipeList: state.recipesReducer }; }

その上で今度はひとつ手前のところで、mapStateToPropsの引数に渡ってくるstateに期待通りの値が存在しているかをチェックしてみましょう。

ここで問題がなければ、これ以降が原因ですし、ここに問題があれば、その手前のreducer周りに問題があると言えます。(さらにそれより以前のところに問題がある可能性もあります)

投稿2018/05/14 13:32

編集2018/05/14 13:54
HayatoKamono

総合スコア2415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Y-A-A

2018/05/14 13:53

ご回答ありがとうございます。 さっそく const Recipes = ({ recipeList }) => { の点を修正しましたが、同様のエラーが出ております。 追加のコードも載せますのでご確認いただけますでしょうか。 reducers/index.js import {combineReducers} from 'redux'; import RecipesReducer from './RecipesReducer'; //import ActiveRecipe from './ActiveRecipe'; const rootReducer = combineReducers({ RecipesReducer : RecipesReducer, // selectedRecipe: ActiveRecipe }); export default rootReducer; レシピをリストから選択した際はonClickでイベントを呼ぶ予定ですが、現在はリストの表示のみを確認したいので一部コメントアウトしています。 呼び出す予定のイベントに関するコードも念のために下記に貼り付けます。 reducers/ActiveRecipe.js //const ActiveRecipe = (state= null, action) =>{ // switch(action.type){ // case 'RECIPE_SELECTED': // return action.payload; // }; // return state; //} //export default ActiveRecipe; containers/RecipeDetail.js //import React, {Component} from 'react'; //import {connect} from 'react-redux'; //import RecipeDetail from '../components/RecipeDetail'; //const mapStateToProps = state => { // return { // selectedRecipe: state.activeRecipe // } //} //export default connect(mapStateToProps, null)(RecipeDetail) components/RecipeDetail.js //import React from 'react'; //const RecipeDetail = ({SelectedRecipe=[]})=> { // return( // <div> // <p>タイトル:{this.recipe.title}</p> // <p>コメント:{this.recipe.comment}</p> // <p>作者:{this.recipe.author}</p> // </div> // ) // } //export default RecipeDetail; actions/index.js export function selectRecipe(recipe){ return{ type: 'RECIPE_SELECTED', payload: recipe }; } よろしくお願いいたします。
HayatoKamono

2018/05/14 13:56 編集

コメント欄ですとコードブロックが効かず読みづらいので、質問文に追記として追加情報を載せて頂けますか?また、ログ出力の結果も追記して下さい。(※回答の追記を要参照)
HayatoKamono

2018/05/14 13:59 編集

const rootReducer = combineReducers({ recipesReducer : RecipesReducer, }); このように修正して再度、試して見て下さい。
HayatoKamono

2018/05/14 14:03

↑これでエラーが治らない場合は、以下を質問文に反映させて下さい。(少し外に出てしまうので、その間に対応してみて下さいということで) (1)回答に追記したデバッグ参考情報をもとに、各ステップにログを差し込み関連する値を確認。その結果を質問文に追記。 (2)現象を再現するために必要なコードを全て質問文に追記。ただし、現象を再現するにあたり不要なコードはノイズになるので、それらは除外。あくまで現象を再現するための最小限のコードを追記。
Y-A-A

2018/05/14 14:09

回答が遅くなりすみません。 const rootReducer = combineReducers({ recipesReducer : RecipesReducer, }); こちらに書き換えたらリストが表示されました! ありがとうございます。 これは右側のRecipesReducerがreducers/RecipesReducer.jsで書いた配列で、左側がcontainers/RecipeList.jsにあるrecipesReducerだという理解で良いでしょうか? 名前が違うので渡せていなかったんですね…。 本当にありがとうございます。 console.log(state)での確認、これから使わせていただきます。
HayatoKamono

2018/05/14 15:21

> 右側のRecipesReducerがreducers/RecipesReducer.jsで書いた配列で 配列ではありません。RecipesReducers.jsでexportしているものを確認していただくと分かると思いますが、exportしているのは関数です。なので、右側は関数です。 > 左側がcontainers/RecipeList.jsにあるrecipesReducer 「state.recipesReducer」のことですよね?厳密に言うと違いますが、結果的にはそうなります。 combineReducers関数はstate objectを作りますが、そのobjectのkeyとなるのが今回の例でいうと、左側の「recipesReducer」です。なので、state.recipesReducerで参照可能になるという訳です。 ※質問が解決した場合はベストアンサーをつけて質問を閉じて下さい。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問