React.jsで簡易todo listを作ってみた(codepen, github)
プロローグ
React.js公式サイト(英語)
一通りReact.jsのDocumentのinstallationとquick startを実践しながら勉強しました。
実際に自分どこまで理解できたのか知りたいので、簡単なWeb applicationを作ってみようかなと。
初心者向けの課題によく出て来るtodo listを選びました。
この記事の最後に完成したサンプル(codepen)とgithubのリンク貼り付けておりますので、ご参考にしていただければ幸いです。
要件定義
簡易バージョンなので、最低限のものだけ作りたいと思います。
- 書き込める場所
- 保存するボタン
- Todo Listを表示させる
(修正不可、削除不可)
ゴール:
参考サイト(英語)
1. Simple React todo list – Agata Krzywda – Medium
今回の勉強記録はこの記事の内容を整理しつつ、公式サイトと見比べながら書き換えたものになります。
スタート
(ターミナルで)
tutorialでインストールしたReactのcreate-react-appコマンドを使って、todolistフォルダを作成します。
$ create-react-app todolist
フォルダ内に移動します。
$ cd todolist $ npm start
自動的にローカルでブラウザ立ち上がり、React.jsページのデフォルトの状態が表示されます。
そして、エディターでフォルダを開くと、構造は
-node_modules/
-public/
-src/
-package-lock.json
-package.json
-README.md
になっています。
/src/app.js
/src/index.js
デフォルトの書き方は主に記述内容はapp.js内で書いて、index.js内でapp.jsを呼び込んで、/public/index.html内で描きます。
実行されるものはindex.jsなので、今回はapp.jsを使わずに、index.jsだけ使いたいと思います。
import React from 'react'; import ReactDOM from 'react-dom'; ReactDOM.render(<App />, document.getElementById('root')); registerServiceWorker();
いらないものを削除して、これだけ残します。
そして、app classをimportの後に追記します。
formを作って入れます。
import React from 'react'; import ReactDOM from 'react-dom'; class App extend React.Component { render() { return( <div> <form> <input type="text" value="" /> <input type="submit" value="Submit" /> </form> </div> ); } } ReactDOM.render(<App />, document.getElementById('root')); registerServiceWorker();
Appの構造を定義します。
constructor(props) { super(props); this.state = { term: '', items: [] }; }
そして、functionは2つあります。
onChangeはinput内に書いたら、inputのvalueに保存する→[term]
onSubmitは先ほど保存したvalueをstate内のitemsにパスする→[items]
constructor内でfunctionを結びついてから、functionを書きます。
constructor(props) { super(props); this.state = { term: '', items: [] }; this.onChange = this.onChange.bind(this); this.onSubmit = this.onSubmit.bind(this); } onChange(e) { this.setState({ term: e.target.value }); } onSubmit(e) { e.preventDefault(); this.setState({ term: '', items: [...this.state.items, this.state.term] }); }
...this.state.items
という書き方はquick start内には説明してなかったけど、advanced guide内にはありました。
すべての〇〇という意味です。ここはすべてのthis.state.itemsです。
そして、renderで書いてたform内のfunctionと繋げます。
formの書き方こちらを参照してます。
render() { return ( <div> <form onSubmit={this.onSubmit}> <input type="text" value={this.state.term} onChange={this.onChange} /> <input type="submit" value="Submit" /> </form> </div> ); }
最後、todo listを表示するために、functionを作ります。
mapの書き方こちらを参照してます。
function List(props) { const items = props.items; const listItems = items.map((item, index) => <li key={index}> {item} </li> ); return( <ul> {listItems} </ul> ); }
class App内のreturnをを追記して、this.state.itemsと繋げます。
render() { return ( <div> <form onSubmit={this.onSubmit}> <input type="text" value={this.state.term} onChange={this.onChange} /> <input type="submit" value="Submit" /> </form> <List items={this.state.items} /> </div> ); }
最終的にまとめてみると、こうなります。
import React from 'react'; import ReactDOM from 'react-dom'; function List(props) { const items = props.items; const listItems = items.map((item, index) => <li key={index}> {item} </li> ); return( <ul> {listItems} </ul> ); } class App extends React.Component { constructor(props) { super(props); this.state = { term: '', items: [] }; this.onChange = this.onChange.bind(this); this.onSubmit = this.onSubmit.bind(this); } onChange(e) { this.setState({ term: e.target.value }); } onSubmit(e) { e.preventDefault(); this.setState({ term: '', items: [...this.state.items, this.state.term] }); } render() { return ( <div> <form onSubmit={this.onSubmit}> <input type="text" value={this.state.term} onChange={this.onChange} /> <input type="submit" value="Submit" /> </form> <List items={this.state.items} /> </div> ); } } ReactDOM.render ( <App />, document.getElementById('root') );
ブラッシュアップ
テストで何件タスクを入れてみましたが、改善点を見つけました。
例えば、間違えてenter(return)を押したら(=submitボタンを押したら)、空白のままでリストに入っちゃうので、それをブロックしたいです。
最後に空白なら追加しないようにonSubmit functionに条件入れます。
onSubmit(e) { e.preventDefault(); if(this.state.term){ this.setState({ term: '', items: [...this.state.items, this.state.term] }); } }
これで間違えて押しても追加されません!
Todo Listの完成体はこちらです!
(はじめてCodepenを導入してみました!)
See the Pen Todo list made by React.js by manmanrai (@manmanrai) on CodePen.
Githubでソースコードアップしました。
※ディレクトリやファイルほぼデフォルトのままです。手入れたファイルはindex.jsのみになってます。