kindle本「ReactでCRUD操作を行ってみよう」のまとめ。
点数
71点
感想
前半はRESTやFetch APIの説明であり、実質は後半のみだった。
簡単な内容ばかりで、少々物足りなく感じた。
REST API
CRUDのHTTPメソッドとURIが紹介されているサイト
JSONPlaceholder - Free Fake REST API
CRUD操作のHTTPメソッド、URI、レスポンスは以下のようになる
CRUD | HTTPメソッド | URI | 成功時のステータスコード |
登録 | POST | /posts | 201 |
取得 | GET | /posts, /posts/100 | 200 |
更新 | PUT | /posts/100 | 204 |
削除 | DELETE | /posts/100 | 204 |
PostmanというWeb APIのテストやドキュメント作成ができるソフトがある
https://www.postman.com/downloads/
※実行時にユーザー登録を求められるが、一番下のSki signing…でスキップできる
JSON Server
REST APIのモックを簡単に作ることができるNode.jsライブラリ。
インストール
npm install json-server
以下のようなJSONファイルを用意
{
"sites": [
{
"id": 1,
"name": "Google",
"url": "https://google.com"
}
]
}
実行
json-server --watch JSONファイル
実行すると以下のようなURLでREST APIにアクセスできるようになる。
- GET, POST
http://localhost:3000/sites - GET, PUT, DELETE
http://localhost:3000/sites/1
Fetch API
- IEは非対応
- 404や505の場合でもエラーにはならない(catchブロックに入らない)ので注意
- POST, PUT, DELETEの場合は第2引数を渡す
※パラメータはオブジェクトをJSON.stringify()で文字列にする
// GET
fetch('https://jsonplaceholder.typicode.com/users/1')
.then((res) => res.json())
.then((user) => console.log(user.name))
.catch((err) => console.log(err));
// POST
fetch('./get-json.php', {
method: 'POST',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({id: 555})
})
.then((res) => {
console.log(res.status);
return res.json()
})
.then((data) => console.log(data))
.catch((err) => console.log(err));
ReactでCRUD
npm init -y; npm install create-react-app
npx create-react-app crud-app
- App.jsを修正
json-server --watch JSONファイル
(JSON Serverサーバの起動)npm start
JSON Serverとは別コンソールで行う。
ポート3000が使用中のため別ポートの使用を求められるのでyを入力。
import React, {Component} from 'react';
import logo from './logo.svg';
class App extends Component {
constructor(props) {
super(props);
this.state = {
siteName: '',
siteURL: '',
sites: [],
}
}
componentDidMount() {
fetch('http://localhost:3000/sites')
.then((res) => res.json())
.then((sites) => this.setState({sites: sites}))
.catch((err) => console.log(err));
}
handleNewNameInput = (e) => {
this.setState({siteName: e.target.value});
}
handleNewUrlInput = (e) => {
this.setState({siteURL: e.target.value});
}
handleCreateData = () => {
if (this.state.siteName === '' || this.state.siteURL === '') {
return;
}
fetch('http://localhost:3000/sites', {
method: 'POST',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({name: this.state.siteName, url: this.state.siteURL})
})
.then((res) => res.json())
.then((site) => {
const sites = this.state.sites;
sites.push(site);
this.setState({
sites: sites,
siteName: '',
siteURL: ''
})
})
.catch((err) => console.log(err));
}
render() {
return (
<div>
<p><input type="text" value={this.state.siteName} onChange={this.handleNewNameInput} placeholder="Name"/></p>
<p><input type="text" value={this.state.siteURL} onChange={this.handleNewUrlInput} placeholder="URL"/></p>
<p>
<button onClick={this.handleCreateData}>Create</button>
</p>
<h3>Todoリスト</h3>
<ul>
{
this.state.sites.map((site, i) => {
return (
<li key={site.url}>{i} {site.name} {site.url}</li>
)
})
}
</ul>
</div>
);
}
}
export default App;
ルーティングを追加
npm install react-router-dom
- コンポーネントSiteListとAddListを追加しApp.jsにルーティングを追加
import React, {Component} from 'react';
class SiteList extends Component {
constructor(props) {
super(props);
this.state = {
sites: [],
}
}
componentDidMount() {
fetch('http://localhost:3000/sites')
.then((res) => res.json())
.then((sites) => this.setState({sites: sites}))
.catch((err) => console.log(err));
}
render() {
return (
<div>
<p><a href="/sites/add">登録フォームへ</a></p>
<h3>Siteリスト</h3>
<ul>
{
this.state.sites.map((site, i) => {
return (
<li key={site.url}>{i} {site.name} {site.url}</li>
)
})
}
</ul>
</div>
);
}
}
export default SiteList;
import React, {Component} from 'react';
class AddSite extends Component {
constructor(props) {
super(props);
this.state = {
siteName: '',
siteURL: '',
}
}
handleNewNameInput = (e) => {
this.setState({siteName: e.target.value});
}
handleNewUrlInput = (e) => {
this.setState({siteURL: e.target.value});
}
handleCreateData = () => {
if (this.state.siteName === '' || this.state.siteURL === '') {
return;
}
fetch('http://localhost:3000/sites', {
method: 'POST',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({name: this.state.siteName, url: this.state.siteURL})
})
.then((res) => res.json())
.then(() => {
this.setState({
siteName: '',
siteURL: ''
})
})
.catch((err) => console.log(err));
}
render() {
return (
<div>
<p><a href="/">Siteリストへ</a></p>
<h3>登録フォーム</h3>
<p><input type="text" value={this.state.siteName} onChange={this.handleNewNameInput} placeholder="Name"/></p>
<p><input type="text" value={this.state.siteURL} onChange={this.handleNewUrlInput} placeholder="URL"/></p>
<p>
<button onClick={this.handleCreateData}>Create</button>
</p>
</div>
);
}
}
export default AddSite;
import React, {Component} from 'react';
import { Route, BrowserRouter } from 'react-router-dom';
import SiteList from './SiteList';
import AddSite from './AddSite';
class App extends Component {
render() {
return (
<BrowserRouter>
<Route path="/" component={SiteList} exact/>
<Route path="/sites/add" component={AddSite} exact/>
</BrowserRouter>
);
}
}
export default App;
Bootstrapを追加
index.htmlに追加
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
任意のタグにclassName属性を追加
※ class属性ではないので注意
- list-group
<ul className="list-group">
<li className="list-group-item">xxxxxxxx</li>
</ul> - card
<div className="card">
<div className="card-header">xxxxxxxx</div>
<div className="card-body">xxxxxxxx</div>
</div>
Loop Back
ログイン認証用REST APIのモックを簡単に作ることができるNode.jsライブラリ。
- インストール
npm install loopback-cli
- アプリケーション作成(プロジェクトのようなもの)
lb
- カレントディレクトリの変更
cd アプリ名
- 実行
node .
※表示されるURLにアクセスすることでAPI一覧の確認が可能