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

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

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

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

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

Q&A

解決済

1回答

2328閲覧

[React]シンプルなTodoアプリを作成中。formからデータが受け取れず困っています。

uk_63

総合スコア29

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

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

0グッド

0クリップ

投稿2019/01/06 13:06

編集2019/01/06 13:12

#実現したいこと

質問を見て下さってありがとうございます。

formからデータを受け取って、配列に追加、setStateして、一覧表示したいです。

#問題
formから取得できるはずのデータが取得できず、undefinedになってしまいます。console.log(event.target.value)が未定義に....

#実際のコード

練習で作っているので、一つのファイルにまとめて書いています。
見やすいようにコメントをつけました。

js

1import React from "react"; 2import ReactDOM from "react-dom"; 3 4import "./styles.css"; 5 6// form - ここにstateをもたせるべきか 7class TodoInput extends React.Component { 8 render() { 9 return ( 10 <> 11 <input name="title" type="text" placeholder="タイトルを入力" /> 12 <br /> 13 <textarea name="description" type="text" placeholder="内容を入力" /> 14 <br /> 15 <button onClick={this.props.handleSubmit}>追加</button> 16 </> 17 ); 18 } 19} 20 21// todoの一つの要素を表すコンポーネント 22const TodoItem = props => { 23 return ( 24 <> 25 <li>{props.title}</li> 26 <li>{props.description}</li> 27 </> 28 ); 29}; 30 31// データを受けて一覧表示させている 32class TodoList extends React.Component { 33 render() { 34 const list = this.props.tasks.map(task => { 35 return <TodoItem {...task} key={task.id} />; 36 }); 37 return ( 38 <> 39 <ul>{list}</ul> 40 </> 41 ); 42 } 43} 44 45// 親コンポーネント、stateをここに固めたい。 46// formで入力した情報をクリックしたらsetStateしたい。 47class App extends React.Component { 48 constructor() { 49 super(); 50 this.state = { 51 tasks: [], 52 uniqueId: 1 53 }; 54 } 55 56 handleClick(e) { 57 // 入力情報がeventに反映されていない 58 const newTitle = e.target.title.value; 59 const newDescription = e.target.description.value; 60 const newUniqueId = this.state.uniqueId + 1; 61 const newTasks = this.state.tasks.slice(); 62 63 newTasks.push({ 64 title: newTitle, 65 description: newDescription, 66 id: newUniqueId 67 }); 68 69 this.setState({ newTasks }); 70 71 e.target.title.value = ""; 72 e.target.description.value = ""; 73 } 74 75 resetTodo = () => { 76 this.setState({ 77 tasks: [] 78 }); 79 }; 80 81 render() { 82 return ( 83 <> 84 <p>Todo App</p> 85 <button onClick={this.resetTodo}>一括削除</button> 86 <br /> 87 <TodoInput handleSubmit={this.handleClick.bind(this)} /> 88 <TodoList tasks={this.state.tasks} /> 89 </> 90 ); 91 } 92} 93 94const rootElement = document.getElementById("root"); 95ReactDOM.render(<App />, rootElement); 96

#どうかご回答お願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは。

いくつかの点で修正したソースを以下に回答します。

主となる修正は、ご質問のタイトルにある、「formからデータが受け取れず困っています。」 に対して、

  • Appthis.state にフォームから入力された値を持たせ、これを変更するメソッドを追加し、<input /> および <textarea />onChangeハンドラに設定

したことです。以下、修正後のソースです。

JSX

1import React from "react"; 2import ReactDOM from "react-dom"; 3 4import "./styles.css"; 5 6// 新規Todo入力フォーム 7const TodoInput = ({ title, description, handleChange, handleSubmit }) => ( 8 <> 9 <input 10 name="title" 11 type="text" 12 placeholder="タイトルを入力" 13 value={title} 14 onChange={handleChange} 15 /> 16 <br /> 17 <textarea 18 name="description" 19 placeholder="内容を入力" 20 value={description} 21 onChange={handleChange} 22 /> 23 <br /> 24 <button onClick={handleSubmit}>追加</button> 25 </> 26); 27 28// todoの一つの要素を表すコンポーネント 29const TodoItem = ({ title, description }) => ( 30 <> 31 <li>{title}</li> 32 <li>{description}</li> 33 </> 34); 35 36// データを受けて一覧表示させている 37const TodoList = ({ tasks }) => ( 38 <ul>{tasks.map(task => <TodoItem {...task} key={task.id} />)}</ul> 39); 40 41// 親コンポーネント、stateをここに固めたい。 42// formで入力した情報をクリックしたらsetStateしたい。 43class App extends React.Component { 44 constructor(props) { 45 super(props); 46 this.state = { 47 tasks: [], 48 uniqueId: 1, 49 form: { title: "", description: "" }, 50 }; 51 } 52 53 handleChange = (e) => { 54 this.setState({ 55 form: { ...this.state.form, [e.target.name]: e.target.value }, 56 }); 57 }; 58 59 handleClick = () => { 60 const newTask = { 61 ...this.state.form, 62 id: this.state.uniqueId, 63 }; 64 this.setState({ 65 tasks: [newTask, ...this.state.tasks], 66 uniqueId: this.state.uniqueId + 1, 67 form: { title: "", description: "" }, 68 }); 69 }; 70 71 resetTodo = () => { 72 this.setState({ 73 tasks: [] 74 }); 75 }; 76 77 render() { 78 return ( 79 <> 80 <p>Todo App</p> 81 <button onClick={this.resetTodo}>一括削除</button> 82 <br /> 83 <TodoInput 84 {...this.state.form} 85 handleChange={this.handleChange} 86 handleSubmit={this.handleClick} 87 /> 88 <TodoList tasks={this.state.tasks} /> 89 </> 90 ); 91 } 92} 93 94const rootElement = document.getElementById("root"); 95ReactDOM.render(<App />, rootElement); 96

上記のコードを含むレポジトリを以下に上げています。

 

上記のレポジトリは以下のコミットを古い順に含みます。

  • initial commit :ご質問に挙げられているコードをそのままコピペして、src/index.js を作成し、他のファイルも追加して動くようにしたものです。

  

 

 

 

  • TodoInput, TodoItem, TodoList をFunctional Componentにする : コミットメッセージに若干間違いがありました。TodoInputとTodoListはstateを持つ必要がないことを明示するため、Functional Componentにしました。TodoItem については元からFunctionalですが、return を無くして若干コードを簡素化しました。

以下の画像は、修正後のものを起動してブラウザに表示させ、2つTodoを追加した後、3つ目を入力中の画面キャプチャです。

イメージ説明

以上、参考になれば幸いです。

投稿2019/01/06 15:22

編集2019/01/06 17:53
jun68ykt

総合スコア9058

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

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

uk_63

2019/01/07 00:06

丁寧な回答ありがとうございます。 ひとつ前の質問にも答えてくださった本当に助かりました。 解説もわかりやすく非常に参考になります。 ありがとうございました!
jun68ykt

2019/01/07 00:58

どういたしまして。お役に立てましたようで、よかったです????
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問