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
↑こちらを読みました。しかし英語なので読み違えている部分があるかもしれません。
参考にできるサイトも併せて教えていただけると嬉しいです。
回答1件
あなたの回答
tips
プレビュー