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

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

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

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

React.js

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

Q&A

解決済

1回答

834閲覧

redux-form actionの初期値を表示する

Y-A-A

総合スコア11

Redux

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

React.js

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

0グッド

0クリップ

投稿2018/05/22 13:15

編集2018/05/23 12:41

React, Redux, Redux-formを使って、入力フォームに記入した内容が送信ボタンが押された際にリストに追加されるという仕組みを作りたいです。
Redux-form公式のSimple Form Exampleを元に、入力フォームの内容をアラートで表示するところまでは出来ました。

しかし、入力した内容をリストに反映させようとするとうまくいきません。

Form.js→新規レシピの入力フォーム
RecipeList→レシピのリスト

です。

index.js/actions

export function handleChange(text){ return{ type: 'TEXT_CHANGED', text: text } } export function addRecipe(newrecipe){ return{ type: 'RECIPE_ADDED', payload: newrecipe } }

AddRecipes.js/reducers

const AddRecipes = (state = initialState, action ) => { switch(action.type) { case 'RECIPE_ADDED': return {...state, recipes: action.payload}}; return state } const initialState = { recipes:[ {title: '白米', image: '5c0cdd2fa192df5c7a968734d0c49d7a_s.png', author: 'Aさん', ing:'お米', amount:'1合', howto:'お米を水で研ぐ。'} }; export default AddRecipes;

index.js/actions

import {combineReducers} from 'redux'; import AddRecipes from './AddRecipes'; import {reducer as formReducer} from 'redux-form'; const rootReducer = combineReducers({ form: formReducer, recipes :AddRecipes }); export default rootReducer;

Form.js/containers

import React, {Component} from 'react'; import {Field, reduxForm} from 'redux-form'; import { bindActionCreators } from 'redux'; import {handleSubmit} from '../actions/index'; import {addRecipe} from '../actions/index'; const Form = props => { const {handleSubmit, pristine, submitting} = props; return( <form onSubmit = {handleSubmit}> <div> <h3>新規レシピ</h3> <p>タイトル</p> <Field name = 'newtitle' label = 'newtitle' component="input" /> <p>写真URL</p> <Field name = 'newimg' label = 'newimg' component="input" /> <p>材料</p> <Field name = 'newing' label = 'newing' component="input" /> <p>分量</p> <Field name = 'newamount' label = 'newamount' component="input" /> <p>作り方</p> <Field name = 'newstep' label = 'newstep' component="input" /> <p>コツ・コメント</p> <Field name = 'newcomment' label = 'newcomment' component="input"   /> </div> <div> <button type = "submit" disabled = {pristine || submitting}> 送信 </button> </div> </form> ) } export default reduxForm({ form: 'addedrecipe', fields: ['newtitle', 'newimg', 'newing','newamount','newstep', 'newcomment'] })(Form);

RecipeList.js/containers

import React, {Component} from 'react'; import {connect} from 'react-redux'; import {addRecipe} from '../actions/index'; import {handleSubmit} from '../actions/index'; import {bindActionCreators} from 'redux'; class RecipeList extends Component{ renderList(){ let handleSubmit = (values) => { var data = { newtitle:values.newtitle, newimg: values.newimg, newing: values.newing, newamount: values.newamount, newstep: values.newstep, newcomment: values.newcomment } this.props.addRecipe(data) } return this.props.recipes.map((recipe)=>{ return( <div onClick = {()=> this.props.activeRecipe(recipe)}> <p>{recipe.title}</p> </div> ); }); } render(){ return <ul>{this.renderList()}</ul> } } function mapStateToProps(state){ return { recipes: state.recipes } } export default connect (mapStateToProps, mapDispatchToProps)(RecipeList);

App.js/components

import React, {Component} from 'react'; import RecipeList from '../containers/RecipeList' import Form from '../containers/Form' import { addRecipe } from '../actions'; export default class App extends Component{ render(){ return ( <div> <Form onSubmit={addRecipe}/> <RecipeList /> </div> ); }; }

エラーの内容

AddRecipes.jsでinitialStateを定義しているので最初に読み込んだ時点でリストが出るはずですが、RecipeList.jsで'TypeError: this.props.recipes.map is not a function'のエラーがでます。

試したこと

console.logでinitialStateの内容が渡されているか確認したところ、index.js/reducersのrootReducerまでは渡されているようです。
reducer→container間の受け渡しに失敗しているのでしょうか?

まずはinitialStateを渡してRecipeListに反映させたいです。

参考サイト
redux-formは参考にできる日本語サイトが少なく困っています。

https://tnakamura.hatenablog.com/entry/2016/11/10/redux-form-field-array

↑最初はこちらのサイトを参考にしたのですが、一つのファイルにまとめて書かれているためファイルやフォルダ間の受け渡し方の参考には

https://stackoverflow.com/questions/44487844/how-to-add-data-to-store-through-redux-forms-in-react

↑こちらを読みました。しかし英語なので読み違えている部分があるかもしれません。

参考にできるサイトも併せて教えていただけると嬉しいです。

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

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

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

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

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

HayatoKamono

2018/05/23 00:01 編集

「まずはinitialStateを渡してRecipeListに反映させていです。(原文のまま引用)」ということなので、今回の質問の範囲をまずは初期表示をさせるところまでに変更してください。(要タイトル修正、本文修正) 掲載されているコード量が多いのと、間違っていそうな箇所が散見されるので質問の範囲が広いと回答する側の負担が大きいです。 また、掲載するコードも前の質問のコメント欄でお伝えした通り、今回の質問に不要なコードはコードを読む側にとってノイズとなるので削り、現象を再現できる最小限のコードを用意して掲載してください。(3分の1〜5分の1くらいには削れそうな気がします)※現象を再現する最小限のコードを用意している過程で、原因が特定しやすくなり、自己解決してしまうことも多くなるのでお薦めでもあります。
guest

回答1

0

ベストアンサー

注釈

まずはinitialStateを渡してRecipeListに反映させていです。

今回の質問の範囲を「初期表示が正常にできるまで」とした前提の上で、以下、回答となります。

※ 以前の回答は中途半端にstate更新部分の指摘も含んでおり、紛らわしくなるので削除しました。

回答(編集版)

初期表示が上手くいかないという現象を再現する為に、
掲載コードを最小限に近い状態まで削ったコードが以下です。
※ エラーはそのまま残しています。

-> https://codesandbox.io/s/n3q7zr2v8l

// index.js import React, { Component } from "react"; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; import RecipeList from "./RecipeList"; import rootReducer from './reducers'; const store = createStore(rootReducer); class App extends Component { render() { return <RecipeList />; } } ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );
// reducer.js import { combineReducers } from "redux"; const initialState = { recipes: [ { title: "白米", author: "Aさん" }, { title: "玄米", author: "Bさん" } ] }; const recipeReducer = (state = initialState) => { return state; }; const rootReducer = combineReducers({ recipes: recipeReducer }); export default rootReducer;
// RecipeList.js import React, { Component } from "react"; import { connect } from "react-redux"; class RecipeList extends Component { renderList() { return this.props.recipes.map(recipe => { return ( <div> <p>{recipe.title}</p> <p>by {recipe.author}</p> </div> ); }); } render() { return <ul>{this.renderList()}</ul>; } } function mapStateToProps(state) { console.log("state.recipes", state.recipes); console.log("isArray", Array.isArray(state.recipes)); console.log("state.recipes.map", state.recipes.map); console.log("{}.map", {}.map); console.log("[].map", [].map); return { recipes: state.recipes }; } export default connect(mapStateToProps)(RecipeList);

このように余計なコードを削り落とすだけで、何が原因なのかが見えやすくなるのではないでしょうか?

1ができていない状態で動作確認もせず、その先の2、3に手を出し、そこで初めてエラーの存在に気づくような進め方だと、デバッグもその分、広範囲に及ぶことになり大変になるので、1つずつ着実に動くコードを積み上げるようにして下さい。

※現在の「redux-form Fieldに入力した内容をcontainerへ渡す方法」というタイトルの質問は、1も2もまだ出来ていないのに「3の部分が出来ないので教えて下さい」というような質問になってます。

一応、RecipeList.jsmapStateToProps関数内にconsole.logを差し込んでおいたので、「https://codesandbox.io/s/n3q7zr2v8l」のコンソール画面で、出力されるログを確認してみて下さい。その上で昨晩回答欄に追記した内容とログの結果、また、ご自身で書かれたrenderListメソッド内のコードを照らし合わせ、何を変えれば良いのかを考えてみて下さい。

投稿2018/05/22 13:54

編集2018/05/23 02:54
HayatoKamono

総合スコア2415

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

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

Y-A-A

2018/05/22 14:10

const newState内が配列ではなく複数のオブジェクトになってしまう、ということでしょうか? 理想はinitialStateの配列の最後に入力した内容を足していきたいです。 簡易化してくださった例ですと const newState = { ...state.recipes, payload.recipes }; ですか?
Y-A-A

2018/05/22 14:10

入れ違いですみません。追記確認しますので少々お待ち下さい。
HayatoKamono

2018/05/22 14:13

食事に出てしまうので、ご自身で全体のコードと切り離した動作確認用のコードを書いて、動作確認を行ってみてください。
HayatoKamono

2018/05/29 10:20 編集

投稿した回答は、とりあえず今回の質問に関係しそうな部分のコードのみにざっと目を通して回答をしたものなので、他にも修正すべき箇所はあるようですが、初期表示の問題に関する主な原因部分は指摘した通りだと思います。
Y-A-A

2018/05/23 12:48

回答が遅くなりすみません。 昨晩アドバイスを頂いたとおり初期値を配列に変え、キー名を変更したところ初期値の表示は出来ましたので質問を閉じさせていただきます。 質問文が不適切だった件について、不要ファイルは載せずにいましたが追記してくださったようにコードも削るものなのですね。タイトルと本文変更いたしました。 独学で普段は人に質問をする機会も無いため、質問に不完全な部分があったことをお詫びいたします。
HayatoKamono

2018/05/29 10:20 編集

このサイトに従わないといけない必須のルールというものは利用規約以外にはなく、コードを削るのは必須では勿論ないのですが、回答する側としては不要なコードはない方が助かります。 ただし、人によっては真逆のことを言うかもしれないので、理想は必要最小限の現象を再現できるコードと、全部載せのコードの両方を載せることかもしれません。
HayatoKamono

2018/05/23 13:45 編集

こちらの「質問のヒント 3-5」のアドバイス欄にかかれていることが上で述べた「不要なコードを削る」ことに関連しているので、参考になるかと思います。https://teratail.com/help/question-tips#questionTips3-5 また、現象を再現する最小限のコードを用意することは、「https://teratail.com/help/question-tips#questionTips1-1」の「お願い」のところに書かれているような誤解を回避することにも繋がるかと思います。 全体的に「質問のヒント」には良いことが書かれているので一通り読んでみることをお勧めします。 ちなみに、Y-A-Aさんの質問はTeratailに投稿される質問の中では質問の質がだいぶ高い方だと思いので安心してください。情報不足な質問、何を言っているか伝わってこない質問がこのサイトは非常に多いので。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問