こんにちは。21Bのmehm8128です。この記事は新歓ブログリレー10日目の記事です。
普段はSysAd班でフロントエンドを担当してWebアプリを作っています。アルゴリズム班で競プロもしてます。
次回 → https://trap.jp/post/1487/
Github(今回の最終的なコードを確認できます) → https://github.com/mehm8128/ToDoList/tree/day-1
この記事について
今回はReactでToDoリストを作っていきたいと思います。traPでは入部後に数日で強強エンジニアになるための「Webエンジニアになろう講習会」という講習会が開かれますが、traPのサービスのフロントエンドが基本的にVueで作られているということもあり、VueでToDoリストを作る課題があります。
そこで今回はそれをVueではなくて僕が普段使っているReactを使って作るという記事です。
WebサイトはHTMLというマークアップ言語やJavaScriptというプログラミング言語で書かれていてそれを表示していますが、ReactやVueというのはHTMLやJavaScriptをもっと簡単に書けるようにした、みたいな感じのものです。
ReactはTwitterやInstagram、Discord、はてなブログなどで使われてるらしいです。
ちなみにReactの公式日本語ドキュメントはこちらです。必要に応じてこのサイトのリンクを貼っていきたいと思います。新歓ブログということもあって日本語のドキュメントを貼りましたが、これは英語ドキュメントを和訳したものなので本当は英語ドキュメントの方が変な解釈ミスなどもなくていいと思います。
また、知らない言葉が出てきたり、エラーが出てきたりしたら適宜自分で言葉やエラー文で検索するといいと思います。プログラミングで大事なのは調べる能力です。そして、調べても分からなければコメント欄で質問してください。
前編の最終形はこんな感じです。
目次
- この記事について
- 目次
- 本編
- Hello World!
- 文字入力部分の作成
- リストの表示
本編
Hello World!
それでは早速作っていきましょう。
ちなみに今回はVSCodeというエディタを使います。Node.jsがインストールされている前提で進めていきますが、インストールされていない場合はインストールするか、環境構築は大変なのでCodeSandBoxを使うのもありだと思います。その場合、テンプレート選択画面でReactを選択(下の画像の赤丸で囲ってあるところをクリック)すればエディタ画面が出てくると思うのでそこにコードを書いてCtrl+S
で保存すれば右側の画面に反映されていきます。反映されない場合はリロードしてみてください。
CodeSandBoxでない方は
npx create-react-app <アプリ名>
でReactのプロジェクトを作成できます。
ディレクトリ構成はこのようになっています(CodeSandBoxの方は少し違うと思います)。
まず
npm start
すると、自動でlocalhost:3000が立ち上がり、↓のような画面が出てくると思います(CodeSandBoxの方は最初から右側に画面があるので問題ないです、出ている画面も違うと思います)。
そしたらエディタに戻り、srcディレクトリ(フォルダとも言う)にcomponentsディレクトリを作り、その中にToDoList.jsというファイルを作成します。ファイルやディレクトリの作成は左側のファイル一覧で右クリックとかそれっぽいアイコンをクリックしたりすればできると思います。
そして、ToDoList.jsとApp.jsを以下のように書き換えます。
src/components/ToDoList.js
function ToDoList() {
return (
<div>
<h1>Hello World!</h1>
</div>
)
}
export default ToDoList
src/App.js
import ToDoList from "./components/ToDoList"
function App() {
return (
<div>
<ToDoList />
</div>
)
}
export default App
return()の()の中には基本的にHTMLのようなものを書いていき、それ以外の部分にJavaScriptを書いていくことになります。ちなみにHTMLは見た目を、JavaScriptは機能を書いていくと思ってください。
そして、この状態で保存すると先ほど開かれた画面に"Hello World!"という文字が表示されます。
これはまず、App.jsというファイルが読み込まれ、returnの中に<ToDoList />
と書いてあるのでToDoListがあるファイルを読み込んで、その中身を表示しています。
このようにしてどんどんコードを書いていってToDoリストを作ります。
今回入れる機能としては
- タスクを追加できる。
- それぞれのタスクが完か未完の状態を持っている。
- タスクを完と未完に分けて表示する。
- 未完のタスクを完にできる。
です。
今回は前編ということで、とりあえずタスクを追加して、完・未完で分けずに表示するところまでやります。
文字入力部分の作成
次にToDoList.jsをこのように書き換えます。
src/components/ToDoList.js
import { useState } from "react"
function ToDoList() {
const [todos, setTodos] = useState([])
const [todo, setTodo] = useState("")
function handlePush() {
if (todo !== "") {
setTodos(todos.concat([todo]))
setTodo("")
}
}
return (
<div>
<h1>ToDoリスト</h1>
<input value={todo} onChange={(e) => setTodo(e.target.value)} />
<button onClick={handlePush}>登録</button>
</div>
)
}
export default ToDoList
ReactではuseStateというものを使って状態管理をしています。useStateを使って定義した変数は値が変化すると画面上の表示でも変化してくれます。
useStateを含む、use~の詳細
const [todos, setTodos] = useState([])
ここではtodosという変数とそれを変更する関数setTodosを定義し、useState()の()の中ではtodosの初期値を設定しています。今回はtodosは配列にしてその中にタスクを入れていきたいので初期値は空の配列にしています。
また、
const [todo, setTodo] = useState("")
ここでは追加するタスクの名前を入れる変数を同じくuseStateを使って宣言しています。名前なので初期値は空の文字列です。
return()の中でJavaScriptの書き方をしたい場合は{}で囲います。
<input value={todo} onChange={(e) => setTodo(e.target.value)} />
<button onClick={handlePush}>登録</button>
ここではinputタグでは文字を入力できるフォームを、buttonタグでは入力した文字を送信するボタンを作っています。onChangeではフォーム内の文字が変更されたときにtodoを変更し、onClickではボタンがクリックされたときにhandlePushという関数を呼び出しています。
フォームの詳細
function handlePush() {
if (todo !== "") {
setTodos(todos.concat([todo]))
setTodo("")
}
}
ここではhandlePush関数を定義しています。新しくタスクを追加する関数です。
if文を使ってtodo(タスク)が空文字列の場合にはタスクの追加をしないようにしています(実装上は空でない場合だけ追加するようにしています)。
setTodosでtodos(タスクリスト)に新しいtodo(タスク)を追加したものを新しくtodosとして変更します。配列.concat()は配列に引数の配列を結合した配列を生成するものです。Array.prototype.concat()
最後に、フォームに入力された文字をリセットしています。
イベントハンドリングの詳細
リストの表示
次にtodosをリストとしてこの下に表示します。
src/components/ToDoList.js
return (
<div>
<h1>ToDoリスト</h1>
<input value={todo} onChange={(e) => setTodo(e.target.value)} />
<button onClick={handlePush}>登録</button>
<h2>タスク一覧</h2>
<ul>
{todos.map((todo, index) => (
<li key={index}>{todo}</li>
))}
</ul>
</div>
)
returnの中だけ書きました。
ulタグが増えていますね。
todos配列の中から1つずつ要素を取ってきて、liタグで表示しています。
mapの第一引数(todo)(タスクを追加する際のtodo変数とは別物です)にはtodos配列の中の要素、第二引数にはtodos配列のindexが入ります。
key={index}というのはリストの要素が削除・変更・追加されたときにReactが検知するために使います。詳しくはドキュメント参照。
実はkeyをindexにするのはよろしくない場合が多いらしいのですが、今回はとりあえずこれでいかせてもらいます。後でそれぞれのタスクにIDを割り当ててそれをkeyにする作業をすることになります。
リストの詳細
これでひとまず、フォームにタスクの名前を入力して登録ボタンを押したら下のリストに表示されるようになりました!
なりましたか?
なったなら前半はこれでおしまいです。上手くいかなかったらコードが間違っていないか確認してみて下さい。
今回の全体のコードへのリンクを再掲しておきます。
https://github.com/mehm8128/ToDoList/tree/day-1
明日は中編ということでいよいよ完・未完でリストを分けて表示し、未完のタスクを完の状態にできるようにします。余裕のある人はどう実装するか考えてみてください。
明日の担当は自分とゆきくらげくんです。お楽しみに!