スポンサーリンク

【React】Todoアプリを作成してみた①

【React】Todoアプリを作成してみた①JavaScript
【React】Todoアプリを作成してみた①
スポンサーリンク

Reactの復習もかねてTodoアプリを作成しました!

学んだことをまとめてみたいと思います。

動作環境

エディションWindows 11 Home
バージョン21H2
Node18.15.0
動作環境

開発環境

React

「Reactを最低限の構成で動かしてみる」で作成したひな型を使います。

Reactを最低限の構成で動かしてみる

CSSフレームワーク

WebページのデザインにMaterial-UIを使用

Material UI は、Google のMaterial Designを実装するオープンソースの React コンポーネント ライブラリです。

https://m2.material.io/
Overview - Material UI
Material UI is a library of React UI components that implements Google's Material Design.

あらかじめデザインされたコンポーネントを使うことで簡単にWebページの見た目を整えることができます。複数で開発する際、デザインを統一できるメリットもあります。

Material-UI

MUI: The React component library you always wanted
MUI provides a simple, customizable, and accessible library of React components. Follow your own design system, or start with Material Design.

ユーザーインターフェース設計

ユーザーインターフェース設計にFigmaを使用

無料で使用できるユーザーインターフェース設計ツール。Material-UIのテンプレートも用意されているので開発時にほぼ同じデザインでWebページを作成できる。

Figma

Figma: The Collaborative Interface Design Tool
Figma is the leading collaborative design tool for building meaningful products. Seamlessly design, prototype, develop, and collect feedback in a single platfor...

おすすめのFigmaテンプレート

①Material 2 Design Kit

基本的なコンポーネントデザインとワイヤーフレームが用意されています。今回は使いませんでしたが、もしMaterial-UIを使う場合はとても役に立つ。

Material 2 Design Kit | Figma Community
Customize and Create Material Design's Baseline Design Kit provides all you need to create beautiful apps, complete with components and theming guidance. Sugges...

②Material Design Icons

様々な視覚的にわかりやすいiconが用意されています。今回は追加と削除ボタンに使用しました。

Material Design Icons | Figma Community
This is the official Material Design icon stickersheet managed by Google Fonts team! Material Design Icons are available in five styles. The icons are crafted b...

機能設計

追加ボタンを押すとフォームに入力された値と削除ボタンが画面に表示される。

削除ボタンを押すとフォームに入力された値と削除ボタンが削除される。

追加ボタンで追加したフォームの値を編集できる。

ワイヤーフレーム

Figmaで作成したユーザーインターフェースを使ってTodoアプリを作成しました。

+(追加)ボタンを押すとTodoリストに入力値が追加され一覧表示されるイメージ。

一覧表示されたTodoリストには編集と削除の機能がある。

TodoPage

Todoアプリの構成

3つのコンポーネントを新しく作成しました。

TodoPage、TodoForm、TodoList、各コンポーネントの役割は以下となります。

TodoPageはTodoFormとTodoListをレンダリングする親コンポーネントの役割をします。

TodoFormは値を入力するフォームと追加ボタンを定義して親コンポーネント(TodoPage)に返却します。

TodoListはTodoFormで入力した値を表示させるフォームと削除ボタンを定義して、親コンポーネント(TodoPage)に返却します。

詳細はコンポーネントの説明にて説明します。

src
│  index.jsx
│
├─components
│      TodoForm.jsx
│      TodoList.jsx
│
└─pages
        TodoPage.jsx

コンポーネントの説明

index.jsx

画面にTodoPageコンポーネントをレンダリングしています。

import React from 'react';
import ReactDOM from 'react-dom/client';
import { TodoPage } from './pages/TodoPage';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<TodoPage />);

TodoPage.jsx

親コンポーネントのTodoPageに定義した内容を説明します。

const [todo, setTodo] = useState('');
const [todoList, setTodoList] = useState([]);

まずは親のコンポーネントにフォームから入力した値を保持するためreact hookのuseStateで状態保持変数(todo,todoList)と状態更新関数(setTodo,setTodoList)を定義しています。

フォームから入力された値(todo)を配列(todoList)に格納していきます。

<TodoForm todo={todo} setTodo={setTodo} todoList={todoList} setTodoList={setTodoList} />        

TodoFormコンポーネントに状態保持変数(todo,todoList)と状態更新関数(setTodo,setTodoList)をprops(引数)として渡します。渡されたpropsはフォームから入力された値を配列(todoList)に追加するために使用します。

<TodoList todoList={todoList} setTodoList={setTodoList} />

TodoListコンポーネントに状態保持変数(todoList)と状態更新関数(setTodoList)をprops(引数)として渡します。渡されたpropsは配列(todoList)の中身を参照・更新・削除するために使用します。

最終的に親のコンポーネント(TodoPage)のレンダリング結果を画面に返却します。

import { useState } from 'react';
import { Container, Box } from '@mui/material';
import { TodoForm } from '../components/TodoForm';
import { TodoList } from '../components/TodoList';

export const TodoPage = () => {
    const [todo, setTodo] = useState('');
    const [todoList, setTodoList] = useState([]);
    return (
        <Box>
            <Container maxWidth='xs'>
                <h1>TODO LIST</h1>
            </Container>
            <TodoForm todo={todo} setTodo={setTodo} todoList={todoList} setTodoList={setTodoList} />
            <TodoList todoList={todoList} setTodoList={setTodoList} />
        </Box>
    );
};

TodoForm.jsx

子コンポーネントのTodoFormに定義した内容を説明します。

setTodo(e.target.value);

onChangeイベントは親のコンポーネントから渡された状態更新関数(setTodo)でフォームに入力された値を更新します。

setTodoList([...todoList, todo]);

スプレッド構文にてtodoListとtodoをマージしています。

onClickイベントは親のコンポーネントから渡された状態更新関数(setTodoList)でフォームに入力された値を配列(todoList)に追加後、更新します。

これらの更新結果をもとにTodoListコンポーネント内で状態保持変数(todoList)に格納された値の数だけ入力フォームと削除ボタンを作成していきます。

import { Container, Box, TextField, IconButton } from '@mui/material';
import AddIcon from '@mui/icons-material/Add';
export const TodoForm = (props) => {
    const { todo, setTodo, todoList, setTodoList } = props;
    return (
        <Container maxWidth='xs'>
            <TextField
                id='inputTodo'
                label=''
                type='text'
                name='inputTodo'
                value={todo}
                onChange={(e) => {
                    console.log('inputTodo:onChange');
                    setTodo(e.target.value);
                }}
                variant='outlined'
            />
            <IconButton
                aria-label='add'
                size='large'
                type='submit'
                onClick={() => {
                    console.log('addButton:onClick');
                    setTodoList([...todoList, todo]);
                }}
            >
                <AddIcon fontSize='inherit' />
            </IconButton>
        </Container>
    );
};

TodoList.jsx

子コンポーネントのTodoListに定義した内容を説明します。

map関数を使って親のコンポーネントから渡された状態保持変数(todoList)の値の数だけ入力フォームと削除ボタンを作成して、親のコンポーネント(TodoPage)に返却します。

div要素に一意であるkeyを指定することで無駄な再レンダリングせずに済みます。keyを指定しないと同じ値があった場合、どちらの値が更新されたか識別ができなくなるため全て再レンダリングを行うことになります。

更新処理はmap関数、削除処理はfilter関数を使います。map、filter関数の引数として定義したインデックス番号とコンポーネント生成時のインデックス番号の差異によって更新と削除を行う条件としています。

setTodoList(todoList.map((todo, i) => (index === i ? e.target.value : todo))

onChangeイベントで親のコンポーネントから渡された状態保持変数(todoList)の値をフォームから入力した値に更新します。更新結果を状態更新関数(setTodoList)で更新します。

setTodoList(todoList.filter((todo, i) => index !== i));

onClickイベントで親のコンポーネントから渡された状態保持変数(todoList)の値を削除します。削除結果を状態更新関数(setTodoList)で更新します。

import { Container, Box, TextField, IconButton } from '@mui/material';
import DeleteIcon from '@mui/icons-material/Delete';

export const TodoList = (props) => {
    const { todoList, setTodoList } = props;
    return (
        <Container maxWidth='xs'>
           {todoList.map((todo, index) => {
                return (
                    <div key={index}>
                        <TextField
                            id='outputTodo'
                            label=''
                            name='outputTodo'
                            value={todo}
                            onChange={(e) => {
                                console.log('TodoList:onChange');
                                setTodoList(
                                    todoList.map((todo, i) => (index === i ? e.target.value : todo))
                                );
                            }}
                            variant='standard'
                        />
                        <IconButton
                            aria-label='delete'
                            size='large'
                            type='submit'
                            onClick={() => {
                                console.log('deleteButton:onClick');
                                setTodoList(todoList.filter((todo, i) => index !== i));
                            }}
                        >
                            <DeleteIcon fontSize='inherit' />
                        </IconButton>
                    </div>
                );
            })}
        </Container>
    );
};

完成したTodoアプリ

Todoアプリの追加、編集、削除のデモとなります!

Todo List
GitHub - TokutyTok/react-todoApp at feature/react_todoApp
react_todoApp. Contribute to TokutyTok/react-todoApp development by creating an account on GitHub.

今回学んだこと

ReactのCompornent定義と分割の仕方、propsでのuseStateの受け渡し

Reactの仮想DOM、レンダリング、hook 状態管理(useState)

Reactでのイベント定義、CRUD処理(mapやfilter)

Figmaを使ったUI設計

Material-UIでのデザイン

おすすめの書籍

JavaScriptのおすすめの書籍です。

基本的に構文が載っているため、教科書代わりに使える内容となっています。

Reactの前にとてもお世話になりました。JavaScriptをこれから始める方におすすめです。

おすすめのUdemy講座

ReactでおすすめのUdemy講座を紹介します。

モダンJavaScriptの基礎から始める挫折しないためのReact入門

ReactはJavaScriptの基本的な構文を使用するため、Reactだけの理解では足りないでしょう。

こちらのReact講座は、JavaScriptでのTODOアプリを作成してからReactでのTODOアプリを作成するため、ReactだけではなくJavaScriptを基礎から学ぶことができます。

Reactからいきなり入らずにJavaScriptの基礎から学べる点が、初心者にとてもおすすめできる内容となっています。

【Reactアプリ開発】3種類のReactアプリケーションを構築して、Reactの理解をさらに深めるステップアップ講座

APIを使用してデータを取得したり、react-router-domでのページ遷移を学べるためより実践的な内容となっています。

3種類のReactアプリケーションを作成することができるため、Reactの基礎的な内容を学んだ人におすすめです。

タイトルとURLをコピーしました