原文: How to Perform CRUD Operations using React, React Hooks, and Axios
React を扱っていれば、API リクエストを理解し実装するのはとても難しいと感じられるでしょう。
そこでこの記事では、React 、React Hooks、React Router、Axios を用いて CRUD 操作を実装することにより、そのすべてがどのように機能するかを学んでいきます。
さあはじめましょう。
Node と npm をインストールする方法
まず最初に、Node をシステム内にインストールしましょう。私たちは主にそれを用いて JavaScript のコードを実行します。
Node をダウンロードするには、https://nodejs.org/en/ にアクセスしてください。
Node上に構築された Node パッケージマネージャー (npm) も必要です。それを用いることで、JavaScript アプリ用のパッケージをインストールできます。幸い、npm は Node に備わっているため、個別にダウンロードする必要はありません。
両方のダウンロードが終了したら、ターミナルかコマンドプロンプトを開いて、node -v
と入力してみましょう。これでダウンロードした Node のバージョンを確認します。
React アプリケーションを作成する方法
次に、React アプリケーションを作成するには、ターミナル内で npx create-react-app <Your app name>
と入力しますが、今回は npx create-react-app react-crud
と入力します。
そうすると、パッケージのインストール状態が表示されます。
パッケージのインストールが終わったら、プロジェクトフォルダーへ移動して、npm start
と入力します。
すると、次のような初期状態の React テンプレートが表示されます:
![Screenshot-2021-07-24-124754](https://www.freecodecamp.org/japanese/news/content/images/2022/01/Screenshot-2021-07-24-124754.png)
![Screenshot-2021-07-24-124858](https://www.freecodecamp.org/japanese/news/content/images/2022/01/Screenshot-2021-07-24-124858.png)
React 用の Semantic UI パッケージをインストールする方法
次に、Semantic UI React パッケージをインストールしましょう。Semantic UI は、React 用に作られた UI (ユーザーインターフェース) ライブラリーです。Semantic UI には、テーブル、ボタンなどの機能をもつ多くの UI コンポーネントが、あらかじめ構築されています。
以下のコマンドを、ご自身のパッケージマネージャーに応じて入力すれば、Semantic UI をインストールできます。
yarn add semantic-ui-react semantic-ui-css
npm install semantic-ui-react semantic-ui-css
また、アプリケーションのメインエントリーファイルである index.js に、インストールしたライブラリーをインポートします。
import 'semantic-ui-css/semantic.min.css'
CRUD アプリケーションを構築する方法
では、React を用いて CRUD アプリケーションの構築を始めましょう。
最初に、アプリケーションにヘッダーを追加しましょう。
以下のようにして、App.js ファイル内にヘッダーを追加します:
import './App.css';
function App() {
return (
<div>
React Crud Operations
</div>
);
}
export default App;
次に、ヘッダーを中央に配置しましょう。
親要素 div の、className 属性の値を main に設定してください。それから、App.css ファイル内でフレックスボックスを使用して、ヘッダーを中央に配置しましょう。
import './App.css';
function App() {
return (
<div className="main">
React Crud Operations
</div>
);
}
export default App;
.main{
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #212121;
color: whitesmoke;
}
![Screenshot-2021-07-24-130340](https://www.freecodecamp.org/japanese/news/content/images/2022/01/Screenshot-2021-07-24-130340.png)
これでヘッダーは完全に中央に配置されました。
見た目が少し良くなるように、ヘッダーをより目立たせて、かっこいいフォントを設定する必要があります。そのために、まずは以下のようにして見出しタグをヘッダーの周りに追加します:
import './App.css';
function App() {
return (
<div className="main">
<h2>React Crud Operations</h2>
</div>
);
}
export default App;
次に Google Fonts からフォントをインポートしましょう。 https://fonts.google.com/ にアクセスし、1 つ選択します。
お好みのフォントを選択してください。ただし、この記事の中では Montserrat フォントファミリーを使用します。
フォントを選択したら、次のようにして App.css ファイル内でフォントをインポートしてください:
@import url('https://fonts.googleapis.com/css2?family=Montserrat&display=swap');
では、ヘッダーのフォントを変更しましょう。
<div className="main">
<h2 className="main-header">React Crud Operations</h2>
</div>
このように、見出しタグの className
属性の値を、main-header
に設定してください。
それから、App.css 内で、Montserrat フォントファミリーを追加してください:
.main-header{
font-family: 'Montserrat', sans-serif;
}
![Screenshot-2021-07-24-132749-1](https://www.freecodecamp.org/japanese/news/content/images/2022/01/Screenshot-2021-07-24-132749-1.jpg)
これでヘッダーが変更されたのが確認できます。
CRUD コンポーネントを作成する方法
これから、4 つの CRUD 操作 (Create - 生成、Read - 読み取り、Update - 更新、Delete - 削除) に対応するコンポーネントを作成してみましょう。
src フォルダーの中に、components というフォルダーを作成してください。それから、このフォルダーの中に create、read、update という 3 つのファイルを作成してください。delete については、コンポーネントを追加する必要はありません。
![Screenshot-2021-07-24-133242](https://www.freecodecamp.org/japanese/news/content/images/2022/01/Screenshot-2021-07-24-133242.png)
では、Create (生成) 操作を実装しましょう。
ただそのためには、Mock API を使用する必要があります。この API は作成したデータを偽のサーバーへ送信するもので、単に学習目的で使用します。
それでは、https://mockapi.io/ へアクセスし、アカウントを作成してください。
![mockAPI](https://www.freecodecamp.org/japanese/news/content/images/2022/01/mockAPI.jpg)
プラスボタンをクリックしてプロジェクトを作成してください。
![createProject](https://www.freecodecamp.org/japanese/news/content/images/2022/01/createProject.jpg)
![projectName](https://www.freecodecamp.org/japanese/news/content/images/2022/01/projectName.png)
プロジェクトの名前を入力して、CREATE ボタンをクリックしてください。
![newResorce](https://www.freecodecamp.org/japanese/news/content/images/2022/01/newResorce.png)
NEW RESOURCE ボタンをクリックして新しいリソースを作成してください。
![resorceName](https://www.freecodecamp.org/japanese/news/content/images/2022/01/resorceName.png)
Resorce Name の欄へ名前を入力することを求められますので、使用する名前を入力してください。
![resorceNameFakeData-1](https://www.freecodecamp.org/japanese/news/content/images/2022/01/resorceNameFakeData-1.png)
name、avatar、createdAt などの余分な欄は必要ありませんので削除してください。その後で、CREATE をクリックしてください。
![createFakeAPI](https://www.freecodecamp.org/japanese/news/content/images/2022/01/createFakeAPI.png)
これで、fakeData という名前の、偽の API を作成できました。
fakeData の上でクリックすると、新しいタブで API が開くのを確認できます。現在データベースは空です。
Create コンポーネント用のフォームを作成する方法
次に、Semantic UI ライブラリーが提供しているフォームを使用してみましょう。
Semantic UI React へアクセスし、左側の検索バーの中で Form を検索してください。
![SemanticReactForm](https://www.freecodecamp.org/japanese/news/content/images/2022/01/SemanticReactForm.png)
このようなフォームが表示されるので、上部左側の Try it をクリックして、コードを取得してください。
![FormCode](https://www.freecodecamp.org/japanese/news/content/images/2022/01/FormCode.png)
コードをコピーしたら、次のように create.js ファイルの中に貼り付けてください:
import React from 'react'
import { Button, Checkbox, Form } from 'semantic-ui-react'
const Create = () => (
<Form>
<Form.Field>
<label>First Name</label>
<input placeholder='First Name' />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input placeholder='Last Name' />
</Form.Field>
<Form.Field>
<Checkbox label='I agree to the Terms and Conditions' />
</Form.Field>
<Button type='submit'>Submit</Button>
</Form>
)
export default Create;
では、Create コンポーネントを App.js ファイルの中でインポートしてください。
import './App.css';
import Create from './components/create';
function App() {
return (
<div className="main">
<h2 className="main-header">React Crud Operations</h2>
<div>
<Create/>
</div>
</div>
);
}
export default App;
そうすると次のようになります:
![formInit](https://www.freecodecamp.org/japanese/news/content/images/2022/01/formInit.png)
しかし、ここで問題が発生します – 項目が適切にそろえられていませんし、テキスト入力欄のラベルの色が黒になってしまっています。では、これを修正してみましょう。
create.js ファイルの中で、Form の className の値を create-form
に設定してください。
import React from 'react'
import { Button, Checkbox, Form } from 'semantic-ui-react'
const Create = () => (
<Form className="create-form">
<Form.Field>
<label>First Name</label>
<input placeholder='First Name' />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input placeholder='Last Name' />
</Form.Field>
<Form.Field>
<Checkbox label='I agree to the Terms and Conditions' />
</Form.Field>
<Button type='submit'>Submit</Button>
</Form>
)
export default Create;
そして、 App.css ファイルの中に以下のクラスセレクターを追加してください:
.create-form label{
color: whitesmoke !important;
font-family: 'Montserrat', sans-serif;
font-size: 12px !important;
}
このクラスセレクターはフォームの各欄のラベルを指定して、文字色を whitesmoke に設定しています。また、フォントを変更して、フォントサイズを大きくしています。
では、main という className
のセレクターの中で、flex-direction プロパティーを追加してください。このプロパティーの値を column 方向に設定することで、className
が main である要素の中の各要素が、垂直にそろえられます。
.main{
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #212121;
color: whitesmoke;
flex-direction: column;
}
![columnDirectionForm](https://www.freecodecamp.org/japanese/news/content/images/2022/01/columnDirectionForm.png)
これで、フォームの外観が改善されるのが確認できます。
では次に、フォーム欄からデータを取得してコンソールの中で表示してみましょう。そのために、React の useState
フックを使用します。
create.js ファイルの中で、React から useState
をインポートしてください。
import React, { useState } from 'react';
その後で、First Name、Last Name、チェックボックス用のステート (state) を作成してください。各ステートは、空のストリングまたは false で初期化します。
import React, { useState } from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react'
export default function Create() {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [checkbox, setCheckbox] = useState(false);
return (
<div>
<Form className="create-form">
<Form.Field>
<label>First Name</label>
<input placeholder='First Name' />
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input placeholder='Last Name' />
</Form.Field>
<Form.Field>
<Checkbox label='I agree to the Terms and Conditions' />
</Form.Field>
<Button type='submit'>Submit</Button>
</Form>
</div>
)
}
現在、Create コンポーネントは関数コンポーネントとして機能しているのが確認できます。フックは、関数コンポーネントの中だけで使用できるので、コンポーネントを関数コンポーネントに変更する必要があります。
では、First Name、Last Name、チェックボックスの各欄の値を、setFirstName
、setLastName
、setCheckbox
プロパティーを用いて、それぞれ設定しましょう。
<input placeholder='First Name' onChange={(e) => setFirstName(e.target.value)}/>
<input placeholder='Last Name' onChange={(e) => setLastName(e.target.value)}/>
<Checkbox label='I agree to the Terms and Conditions' onChange={(e) => setCheckbox(!checkbox)}/>
それから、firstName、lastName、checkbox の各ステートの値を取得してみましょう。
ここで、後から API へデータを送信するのに使用する、postData
という名の関数を作成します。その関数の中に、次のコードを記述してください:
const postData = () => {
console.log(firstName);
console.log(lastName);
console.log(checkbox);
}
では、First Name、Last Name、チェックボックスの値をコンソールに出力してみましょう。
Submit ボタンに、onClick イベントを使用してこの関数を割り当てることによって、Submit ボタンを押したときに、この関数が呼び出されるようにします。
<Button onClick={postData} type='submit'>Submit</Button>
これまでの内容をすべて含んだ、create ファイル用のコードはこちらです:
import React, { useState } from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react'
export default function Create() {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [checkbox, setCheckbox] = useState(false);
const postData = () => {
console.log(firstName);
console.log(lastName);
console.log(checkbox);
}
return (
<div>
<Form className="create-form">
<Form.Field>
<label>First Name</label>
<input placeholder='First Name' onChange={(e) => setFirstName(e.target.value)}/>
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input placeholder='Last Name' onChange={(e) => setLastName(e.target.value)}/>
</Form.Field>
<Form.Field>
<Checkbox label='I agree to the Terms and Conditions' onChange={(e) => setCheckbox(!checkbox)}/>
</Form.Field>
<Button onClick={postData} type='submit'>Submit</Button>
</Form>
</div>
)
}
First name と Last name の中に値を入力して、チェックボックスにチェックを入れてください。その後で、Submit ボタンをクリックしてみてください。すると次のように、コンソールの中にデータがポップアップするのが確認できます:
![dataPopUp](https://www.freecodecamp.org/japanese/news/content/images/2022/01/dataPopUp.png)
Axios を使って API リクエストを Mock API へ送信する方法
今度は、Axios を使ってフォームのデータを偽のサーバーへ送信してみましょう。
しかしまずは、Axios をインストールする必要があります。
npm i axios
と入力して、パッケージをインストールしてください。
![AxiosInstall](https://www.freecodecamp.org/japanese/news/content/images/2022/01/AxiosInstall.png)
パッケージのインストールが終了したら、Create 操作の実装を開始しましょう。
Axios をファイルの先頭でインポートしてください。
import axios from 'axios';
postData
関数の中で、Axios を使用して POST リクエストを送信します。
const postData = () => {
axios.post(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData`, {
firstName,
lastName,
checkbox
})
}
ご覧のとおり、ここでは axios.post を使用しています。また axios.post の中に、先ほど作成した API のエンドポイントがあります。その後に、中括弧で囲まれたフォームの項目があります。
Submit をクリックした時に、この関数が呼び出され API サーバーにデータを送信します。
![postFormData](https://www.freecodecamp.org/japanese/news/content/images/2022/01/postFormData.png)
では、First Name と Last Name を入力して、チェックボックスにチェックを入れたら、Submit をクリックしてください。
![postedFormData](https://www.freecodecamp.org/japanese/news/content/images/2022/01/postedFormData.png)
その後で API を確認してみると、オブジェクトの中に囲まれた状態で、入力した First Name と Last Nameの値と、true という値に設定された checkbox を取得できます。
Read 、Update、Delete の各操作を実装する方法
Read (読み取り) 操作の実装を開始するために、Read ページを作成する必要があります。また、React Router パッケージを用いて、ユーザーをさまざまなページへ案内する必要があります。
https://reactrouter.com/web/guides/quick-start へアクセスし、また、npm i react-router-dom@5
を使用してパッケージをインストールしてください。
パッケージのインストールが済んだら、React Router からコンポーネントをいくつかインポートします:
import { BrowserRouter as Router, Route } from 'react-router-dom'
App.js の中で、return の中のコードをすべて Router でラップしてください。基本的に Router の内部にあるものは、 React の中でルーティングを使用できることを意味しています。
import './App.css';
import Create from './components/create';
import { BrowserRouter as Router, Route } from 'react-router-dom'
function App() {
return (
<Router>
<div className="main">
<h2 className="main-header">React Crud Operations</h2>
<div>
<Create />
</div>
</div>
</Router>
);
}
export default App;
現在、App.js は上のような状態でしょう。
では、return 内の Create を置き換えて、以下のコードを追加してください:
import './App.css';
import Create from './components/create';
import { BrowserRouter as Router, Route } from 'react-router-dom'
function App() {
return (
<Router>
<div className="main">
<h2 className="main-header">React Crud Operations</h2>
<div>
<Route exact path='/create' component={Create} />
</div>
</div>
</Router>
);
}
export default App;
ここでは、Create をルートコンポーネントとして使用しています。Create のパスは '/create' に設定しました。そのため、http://localhost:3000/create へアクセスすれば、Create ページを見ることができます。
同じように、read と update に対応するルートが必要です。
import './App.css';
import Create from './components/create';
import Read from './components/read';
import Update from './components/update';
import { BrowserRouter as Router, Route } from 'react-router-dom'
function App() {
return (
<Router>
<div className="main">
<h2 className="main-header">React Crud Operations</h2>
<div>
<Route exact path='/create' component={Create} />
</div>
<div style={{ marginTop: 20 }}>
<Route exact path='/read' component={Read} />
</div>
<Route path='/update' component={Update} />
</div>
</Router>
);
}
export default App;
上のコードで確認できるように、read と update のルートを作成します。
ここで http://localhost:3000/read へアクセスすると、Read ページが次のように表示されます:
![planeReadComponent](https://www.freecodecamp.org/japanese/news/content/images/2022/02/planeReadComponent.png)
また、http://localhost:3000/update では、次のように Update コンポーネントが表示されます:
![planeUpdateComponent](https://www.freecodecamp.org/japanese/news/content/images/2022/02/planeUpdateComponent.png)
Read 操作
Read 操作には、テーブルコンポーネントが必要です。そのため、React Semantic UI にアクセスし、ライブラリーが提供しているテーブルを、以下のように使用してください。
import React from 'react';
import { Table } from 'semantic-ui-react'
export default function Read() {
return (
<div>
<Table singleLine>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Name</Table.HeaderCell>
<Table.HeaderCell>Registration Date</Table.HeaderCell>
<Table.HeaderCell>E-mail address</Table.HeaderCell>
<Table.HeaderCell>Premium Plan</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>John Lilki</Table.Cell>
<Table.Cell>September 14, 2013</Table.Cell>
<Table.Cell>jhlilk22@yahoo.com</Table.Cell>
<Table.Cell>No</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Jamie Harington</Table.Cell>
<Table.Cell>January 11, 2014</Table.Cell>
<Table.Cell>jamieharingonton@yahoo.com</Table.Cell>
<Table.Cell>Yes</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell>Jill Lewis</Table.Cell>
<Table.Cell>May 11, 2014</Table.Cell>
<Table.Cell>jilsewris22@yahoo.com</Table.Cell>
<Table.Cell>Yes</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
</div>
)
}
ここではテーブルの中にいくつかのダミーデータが用いられていますが、1 列分のデータだけが必要なので、残りは削除しましょう。
import React from 'react';
import { Table } from 'semantic-ui-react'
export default function Read() {
return (
<div>
<Table singleLine>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Name</Table.HeaderCell>
<Table.HeaderCell>Registration Date</Table.HeaderCell>
<Table.HeaderCell>E-mail address</Table.HeaderCell>
<Table.HeaderCell>Premium Plan</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>John Lilki</Table.Cell>
<Table.Cell>September 14, 2013</Table.Cell>
<Table.Cell>jhlilk22@yahoo.com</Table.Cell>
<Table.Cell>No</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
</div>
)
}
![reducedRows](https://www.freecodecamp.org/japanese/news/content/images/2022/02/reducedRows.png)
これが Read ページの出力画面です。テーブルには列が 4 つありますが、必要なのは 3 つだけです。
余分な項目の列を削除してから、次のように項目の名前をつけなおしてください:
![reducedColumn](https://www.freecodecamp.org/japanese/news/content/images/2022/02/reducedColumn.png)
すると現在、Read ページはこのように見えます:
import React from 'react';
import { Table } from 'semantic-ui-react'
export default function Read() {
return (
<div>
<Table singleLine>
<Table.Header>
<Table.Row>
<Table.HeaderCell>First Name</Table.HeaderCell>
<Table.HeaderCell>Last Name</Table.HeaderCell>
<Table.HeaderCell>Checked</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>Nishant</Table.Cell>
<Table.Cell>Kumar</Table.Cell>
<Table.Cell>Yes</Table.Cell>
</Table.Row>
</Table.Body>
</Table>
</div>
)
}
では、API から GET リクエストを送信してデータを取得してみましょう。
アプリケーションがマウントされる時に、取得したデータが必要になるので、useEffect
フックを使用して実装してください。
import React, { useEffect } from 'react';
useEffect(() => {
}, [])
ステートを 1 つ作成して、取得したデータを格納します。取得するデータは配列です。
import React, { useEffect, useState } from 'react';
const [APIData, setAPIData] = useState([]);
useEffect(() => {
}, [])
では、useEffect
フックの中で、GET リクエストを送信してみましょう。
useEffect(() => {
axios.get(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData`)
.then((response) => {
setAPIData(response.data);
})
}, [])
ここでは axios.get を使用して、GET リクエストを API へ送信しています。その後で、リクエストが resolve (成功) すれば、レスポンスデータを APIData ステート内に格納します。
続いて、取得した API データに応じてテーブルの行をマッピングしましょう。
そのために Map 関数を使用します。Map 関数は配列を反復処理して、データを出力画面内に表示します。
<Table.Body>
{APIData.map((data) => {
return (
<Table.Row>
<Table.Cell>{data.firstName}</Table.Cell>
<Table.Cell>{data.lastName}</Table.Cell>
<Table.Cell>{data.checkbox ? 'Checked' : 'Unchecked'}</Table.Cell>
</Table.Row>
)})}
</Table.Body>
API 内のデータに応じて、firstName, lastName, checkbox のそれぞれのデータをマッピングしています。また、ここでは三項演算子 ('?') を使用しています。data.checkbox が true である場合は、Checked と表示され、そうでない場合は Unchecked と表示されます。
![ReadOutput](https://www.freecodecamp.org/japanese/news/content/images/2022/02/ReadOutput.png)
Update 操作
それでは、テーブルに Update (更新) 用のヘッダーをもう 1 つ作成し、Update ボタン用の列を、Table.Row の中に作成してください。Update ボタンには、Semantic UI React が提供している Button コンポーネントをインポートして使用してください。
<Table.HeaderCell>Update</Table.HeaderCell>
<Table.Cell>
<Button>Update</Button>
</Table.Cell>
ここで、Update ボタンがクリックされた時に、 Update ページにリダイレクトされる必要があります。そのためには React Router が提供している Link が必要です。
では、React Router から Link をインポートしてください。それから、Link タグの中へ Update ボタン用の Table.Cell をラップしてください。
import { Link } from 'react-router-dom';
<Link to='/update'>
<Table.Cell>
<Button>Update</Button>
</Table.Cell>
</Link>
これで、Update ボタンをクリックした時に、Update ページへリダイレクトされるようになりました。
また、Update ボタンをクリックした時に、各列のデータを更新するには、API が提供している、それぞれの ID が必要です。
setData
という名前の関数をコンポーネントの先頭に作成してください。それから、その関数を Update ボタンにバインドしてください。
<Button onClick={() => setData()}>Update</Button>
ここでは、先頭の関数へ引数としてデータを渡す必要があります。
<Button onClick={() => setData(data)}>Update</Button>
そして、先頭の関数の中で、データをコンソール内に表示させます:
const setData = (data) => {
console.log(data);
}
![updateDataInConsole](https://www.freecodecamp.org/japanese/news/content/images/2022/02/updateDataInConsole.png)
では、update ボタンをクリックして、コンソールを確認してみてください。テーブルの各項目のデータを取得しています。
今度は、このデータをローカルストレージへ格納しましょう。
const setData = (data) => {
let { id, firstName, lastName, checkbox } = data;
localStorage.setItem('ID', id);
localStorage.setItem('First Name', firstName);
localStorage.setItem('Last Name', lastName);
localStorage.setItem('Checkbox Value', checkbox);
}
このようにして、データを id、firstName、lastName、checkbox に分割してから、ローカルストレージへ格納しています。ローカルストレージを使用することで、ブラウザー内でローカルにデータを保存できます。
今ここで、Update コンポーネント内に update 操作用のフォームが 1 つ必要です。Create コンポーネントで用いたフォームを再利用しましょう。関数名を単に Create から Update へ変更するだけです。
import React, { useState } from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react'
import axios from 'axios';
export default function Update() {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [checkbox, setCheckbox] = useState(false);
return (
<div>
<Form className="create-form">
<Form.Field>
<label>First Name</label>
<input placeholder='First Name' onChange={(e) => setFirstName(e.target.value)}/>
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input placeholder='Last Name' onChange={(e) => setLastName(e.target.value)}/>
</Form.Field>
<Form.Field>
<Checkbox label='I agree to the Terms and Conditions' onChange={(e) => setCheckbox(!checkbox)}/>
</Form.Field>
<Button type='submit'>Update</Button>
</Form>
</div>
)
}
useEffect
フックを Update コンポーネント内で作成してください。このフックを使い、前もってローカルストレージへ格納したデータを取り出します。さらに、ID 項目用のステートをもう一つ作成します。
const [id, setID] = useState(null);
useEffect(() => {
setID(localStorage.getItem('ID'))
setFirstName(localStorage.getItem('First Name'));
setLastName(localStorage.getItem('Last Name'));
setCheckbox(localStorage.getItem('Checkbox Value'))
}, []);
それから、ローカルストレージから取り出したデータを、キーに応じて配置します。フォームの各欄の中に、取り出した値を配置する必要があります。Update ページがロードされた時に、各欄の中にデータが自動的に配置されるようにしましょう。
<Form className="create-form">
<Form.Field>
<label>First Name</label>
<input placeholder='First Name' value={firstName} onChange={(e) => setFirstName(e.target.value)}/>
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input placeholder='Last Name' value={lastName} onChange={(e) => setLastName(e.target.value)}/>
</Form.Field>
<Form.Field>
<Checkbox label='I agree to the Terms and Conditions' checked={checkbox} onChange={(e) => setCheckbox(!checkbox)}/>
</Form.Field>
<Button type='submit'>Update</Button>
</Form>
これで、Read ページ内の Update ボタンをクリックすると、Update ページへリダイレクトされ、そこで自動的に配置されたフォームデータを見ることができます。
![populatedDataInUpdatePage](https://www.freecodecamp.org/japanese/news/content/images/2022/02/populatedDataInUpdatePage.png)
それでは、Update リクエストを実装してデータを更新してみましょう。
updateAPIData
という名前の関数を作成してください。この関数の中で、axios.put を用いて PUT リクエストを送信し、データを更新します。
const updateAPIData = () => {
axios.put(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData/${id}`, {
firstName,
lastName,
checkbox
})
}
ここでは API エンドポイントに id 項目を添えているのが確認できます。
Read ページで、項目の Update ボタンをクリックした時に、その ID がローカルストレージの中に格納され、その後に Update ページ で取り出した ID を id
ステートの中に格納しています。
そうした後に、id
をエンドポイントへ渡しています。こうすることで、渡している ID の項目を更新できます。
次に、updateAPIData
関数を Update ボタンにバインドしてください。
<Button type='submit' onClick={updateAPIData}>Update</Button>
Read ページにあるテーブルの中の、Update ボタンをクリックしてから、Last name を変更し、Update ページにある Update ボタンをクリックしてください。
![updatingTheFields](https://www.freecodecamp.org/japanese/news/content/images/2022/02/updatingTheFields.png)
API を確認してみるか、または Read ページへ戻ってみると、last name が変更されているのを確認できます。
![updatedMockAPIData](https://www.freecodecamp.org/japanese/news/content/images/2022/02/updatedMockAPIData.png)
![updatedReadTable](https://www.freecodecamp.org/japanese/news/content/images/2022/02/updatedReadTable.png)
Delete 操作
まずは、Read ページのテーブルに、Delete (削除) 操作用のボタンを 1 つ追加しましょう。
<Table.HeaderCell>Delete</Table.HeaderCell>
<Table.Cell>
<Button>Delete</Button>
</Table.Cell>
次に、onDelete
という名前の関数を作成してから、Delete ボタンにその関数をバインドしてください。この関数は、Delete ボタンをクリックした時に ID パラメータを受け取ります。
const onDelete = (id) => {
}
<Table.Cell>
<Button onClick={() => onDelete(data.id)}>Delete</Button>
</Table.Cell>
では、axios.delete を使用して、それぞれの項目を削除する操作を実装しましょう。
const onDelete = (id) => {
axios.delete(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData/${id}`)
}
Delete ボタンをクリックしてから API を確認してみてください。クリックした項目のデータが削除されているのを確認できます。
ここで、クリックした項目のデータが削除された後に、テーブルのデータをロードし直す必要があります。
そのために、API のデータを読み込む関数を作成してください。
const getData = () => {
axios.get(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData`)
.then((getData) => {
setAPIData(getData.data);
})
}
そして onDelete
関数の中で、項目を削除した後に更新された API のデータを読み込む必要があります。
const onDelete = (id) => {
axios.delete(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData/${id}`)
.then(() => {
getData();
})
}
![ReadTableBeforeDataDeleted](https://www.freecodecamp.org/japanese/news/content/images/2022/02/ReadTableBeforeDataDeleted.png)
これで、今は各項目の Delete ボタンをクリックすることでその項目が削除され、テーブルが自動的に最新の情報に更新されます。
![ReadTableAfterDataDeleted](https://www.freecodecamp.org/japanese/news/content/images/2022/02/ReadTableAfterDataDeleted.png)
CRUD アプリを少し改善してみましょう
これまで、Create ページの中でデータを投稿 (post) する時には、単にデータを偽のデータベースの中へ入れていましたが、その際に Read ページへリダイレクトする必要があります。
それではまず、React Router から useHistory
をインポートしてください。
import { useHistory } from 'react-router';
次に、let
文で history という名前の変数を作成して、その変数の中に useHistory
を格納してください。
let history = useHistory();
その後で、post API が呼び出されてから、POST リクエストが resolve した時に、history.push 関数を使用して Read ページへ移動します。
const postData = () => {
axios.post(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData`, {
firstName,
lastName,
checkbox
}).then(() => {
history.push('/read')
})
}
このように useHistory
フックを用いることで Read ページへ移動できます。
Update ページについても同じことを行ってください。
import React, { useState, useEffect } from 'react';
import { Button, Checkbox, Form } from 'semantic-ui-react'
import axios from 'axios';
import { useHistory } from 'react-router';
export default function Update() {
let history = useHistory();
const [id, setID] = useState(null);
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [checkbox, setCheckbox] = useState(false);
useEffect(() => {
setID(localStorage.getItem('ID'))
setFirstName(localStorage.getItem('First Name'));
setLastName(localStorage.getItem('Last Name'));
setCheckbox(localStorage.getItem('Checkbox Value'));
}, []);
const updateAPIData = () => {
axios.put(`https://60fbca4591156a0017b4c8a7.mockapi.io/fakeData/${id}`, {
firstName,
lastName,
checkbox
}).then(() => {
history.push('/read')
})
}
return (
<div>
<Form className="create-form">
<Form.Field>
<label>First Name</label>
<input placeholder='First Name' value={firstName} onChange={(e) => setFirstName(e.target.value)}/>
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input placeholder='Last Name' value={lastName} onChange={(e) => setLastName(e.target.value)}/>
</Form.Field>
<Form.Field>
<Checkbox label='I agree to the Terms and Conditions' checked={checkbox} onChange={() => setCheckbox(!checkbox)}/>
</Form.Field>
<Button type='submit' onClick={updateAPIData}>Update</Button>
</Form>
</div>
)
}
以上で、React と React フックを使用して CRUD 操作を実行する方法について理解できました!
学習内容を補足したい場合は、React CRUD Operations という YouTube のビデオ を、この記事の代わりに見ることができます。
さらに、コードをテストしてみたい場合は、GitHubでコードを見つけることができます。
ハッピーラーニング