前回作成したTodoアプリを修正していきたいと思います。
今回は修正する部分が多いため本記事ではデータの受け渡し部分の修正を行います。
動作環境
エディション | Windows 11 Home |
バージョン | 21H2 |
Node | 18.15.0 |
開発環境
「ReactでTodoアプリを作成してみた①」で作成したアプリを改修します。
機能設計
Todoリストを未完了、作業中、完了のステータスによって表示場所を振り分ける
未完了→作業中→完了→未完了の順番でTodoが移動するチェックボタンを作成する
ワイヤーフレーム
今回は入力欄を1個とTodoリストを3個表示していきます。
コンポーネントで共通的に表示できるイメージでワイヤーフレームを作成しました。
Todoアプリの構成
共通的にコンポーネントを利用していきたいのでデータの受け渡し部分を修正します。
TodoProvider.jsx TodoOrganism.jsxを新たに追加しました。
親子関係についてはTodoPage→TodoOrganisms→TodoForm,TodoListとなります。
src
│ index.jsx
│
├─components
│ TodoForm.jsx
│ TodoList.jsx
│
├─context
│ TodoProvider.jsx
│
├─organisms
│ TodoOrganisms.jsx
│
└─pages
TodoPage.jsx
コンポーネントの説明
TodoProvider.jsx
コンポーネントの階層が増えた場合propsでのデータの受け渡しが親→子→孫など各コンポーネントごとにpropsでのデータの受け渡しをする必要がでてきます。親で定義したデータを孫で使いたい場合、子で使わないのにpropsでのデータの受け渡しをすると子に無駄にpropsを渡すことになります。親→子→孫など階層が深いデータの受け渡しをバケツリレーともいう。
例:①→②→③ ③で使いたいため②にpropsでデータを受け渡す。
無駄なバケツリレーを避けるためにどのコンポーネントでもデータを使用できるようreact hook useContextを使用します。useContextを使うことでアプリケーション全体でデータの共有をすることができます。
Todoリストに表示する値、配列のuseStateをTodoProviderに定義します。
TodoContext.Providerのpropsに共有したい状態管理変数と関数を渡す。{children}を使うことで親で受け取ったpropsを子に受け渡すことができる。
import { useState, createContext } from 'react';
export const TodoContext = createContext();
export const TodoProvider = ({ children }) => {
const [todo, setTodo] = useState('');
const [todoList, setTodoList] = useState([]);
const [notStartedList, setNotStartedList] = useState([]);
return (
<TodoContext.Provider
value={{ todo, setTodo, todoList, setTodoList, notStartedList, setNotStartedList }}
>
{children}
</TodoContext.Provider>
);
};
index.jsx
TodoPageをTodoProviderで挟むことによって、TodoProvider.jsxで定義したpropsを<TodoPage />コンポーネントに渡すことができます。
これでTodoPage内でデータの共有をする準備完了です。
import React from 'react';
import ReactDOM from 'react-dom/client';
import { TodoPage } from './pages/TodoPage';
import { TodoProvider } from './context/TodoProvider';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<TodoProvider>
<TodoPage />
</TodoProvider>
);
TodoPage
コンポーネントを共通的に利用するためにTodoOrganismsコンポーネントを作成しました。完成系は入力欄コンポーネントが1個、Todoリストの表示するコンポーネントを3個作成します。
import { TodoOrganisms } from '../organisms/TodoOrganisms';
export const TodoPage = () => {
return <TodoOrganisms title={'TODO APP'} />;
};
TodoOrganisms.jsx
TodoフォームやTodoリストを表示させるコンポーネントとなります。
const { todo, setTodo, todoList, setTodoList } = useContext(TodoContext);
TodoProvider.jsxで定義したstateの受け渡しを行うため、TodoProviderのTodoContextを呼び出しuseContextを使用します。
import { useContext } from 'react';
import { TodoContext } from '../context/TodoProvider';
import { Box, Typography } from '@mui/material';
import { TodoForm } from '../components/TodoForm';
import { TodoList } from '../components/TodoList';
export const TodoOrganisms = (props) => {
const { todo, setTodo, todoList, setTodoList } = useContext(TodoContext);
return (
<Box>
<Typography variant='h5' component='h1'>
{props.title}
</Typography>
<TodoForm todo={todo} setTodo={setTodo} todoList={todoList} setTodoList={setTodoList} />
<TodoList todoList={todoList} setTodoList={setTodoList} />
</Box>
);
};
完成したTodoアプリ
データの受け渡し部分をリファクタリングしました。動作は変わっていません。
今回学んだこと
useContextでのデータ共有(global state)
次回
次はTodoリストを未完了、作業中、完了に分けていきたいと思います。
おすすめの書籍
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の基礎的な内容を学んだ人におすすめです。
基本的に構文が載っているため、教科書代わりに使える内容となっています。
Reactの前にとてもお世話になりました。JavaScriptをこれから始める方におすすめです。