React(Typescript)からSinatraで作成したAPIを叩いて、データを取得して展開するみたいな実装をしたのでまとめておきます。TsやSinatraはそんなに経験がないので、間違いがあれば指摘お願いします。
やること
- React+TypeScriptでコンポーネント作成時に、Sinatra上で作成したAPIからデータを取得して、表示するまでの流れ。
対象者
- APIサーバーとフロントサーバーを切り離した時のデータのやり取りについて知りたい人。
- Sitatra上でのAPI作成について知りたい人。
- React + TypeScriptでのデータの取得からの展開の仕方について知りたい人。
扱うこと
- SinatraでのAPI作成方法
- React(TypeScript)側での取得方法
- 取得データをReact側で表示させるまでの流れ
※環境構築には触れないのでご了承ください。
SinatraでAPI作成
Sinatraの基本知識は以下のサイトで確認!
http://sinatrarb.com/intro-ja.html
ここからはAPI部分のみ記述していく。app.rbに以下の感じで書いていく。例として、nameカラムを持つUserテーブルから全てのデータを取得することを想定する。
get '/users' do
@users = User.all
return @users.to_json
end
のちにcorsで困ることになるので、以下のように変更。corsについては以下の記事参照。
https://qiita.com/tomoyukilabs/items/81698edd5812ff6acb34
before do
response.headers['Access-Control-Allow-Origin'] = '*'
end
get '/users' do
@users = User.all
return @users.to_json
end
React(Typescript)でAPIを叩く
先のコードを示す。以下、解説を加えていく。
import * as React from "react";
import axios from "axios";
import camelcaseKeys from 'camelcase-keys';
interface User {
id: number;
name: string;
}
interface State {
users: User[];
}
class User extends React.Component<State> {
constructor() {
super();
this.state = {
users: []
};
}
componentDidMount() {
const url = `https://domain_name/users`
axios.get(url)
.then((results) => {
const data = results.data
const users = data.map((d: object[]) => {
return(camelcaseKeys(d))
})
this.setState({
users
})
})
.catch((data) => {
console.log(data)
})
}
render() {
const { users } = this.state;
return (
<div className="hello">
<p>Users</p>
{users.map((user) => {
return (
<div key={user.id}>
<p>{user.name}</p>
</div>
)
})}
</div>
);
}
}
export default User;
必要なライブラリのimport
以下のコードで必要なライブラリをimport。ReactはComponentを作成するために必要なもの、axiosはAPIを叩くために必要、camelcaseKeysはSinatraから取得したsnake_caseで表現されているデータを書き換えるために必要。
import * as React from "react";
import axios from "axios";
import camelcaseKeys from 'camelcase-keys';
型の定義とStateの準備
取得するデータの型とデータを入れるためのStateの準備。今回取得するデータはidカラムとnameカラムを持つUserなのでその旨を定義する。そしてusersをStateに記述する。
interface User {
id: number;
name: string;
}
interface State {
users: User[];
}
class User extends React.Component<State> {
constructor() {
super();
this.state = {
users: []
};
}
APIを叩く場所
以下のコードでAPIを叩いている。ReactでAPIを叩きたいときはaxiosを利用してgetリクエストを該当urlに投げて結果を取得する。取得するときにhashデータのkeyをsnake_caseからcamel_casenに直す(rubyではsnake_case推奨だがjsでは違う)。componentDidMountについては以下の記事参照。
https://qiita.com/megane42/items/213e927a2af72530e920
componentDidMount() {
const url = `https://domain_name/users`
axios.get(url)
.then((results) => {
const data = results.data
const users = data.map((d: object[]) => {
return(camelcaseKeys(d))
})
this.setState({
users
})
})
.catch((data) => {
console.log(data)
})
}
データの展開とexport
データを展開してexportする。
render() {
const { users } = this.state;
return (
<div className="hello">
<p>Users</p>
{users.map((user) => {
return (
<div key={user.id}>
<p>{user.name}</p>
</div>
)
})}
</div>
);
}
}
export default User;
最後に
ずっとRuby(Rails)使いだったので、TSは非常に新鮮で楽しい。Rubyしか使ったことのない人は型とかのいい勉強になると思うのでオススメです。