背景
ReactでAPIからデータを取得する方法は、少し探せばたくさんヒットします。Axiosを使うのが定番ですね。
ところがTypeScript環境だと参考になる情報が急に少なくなります。
検証した環境
- React v18.2.0
- Axios v1.3.4
- Windows 11
Linuxでも同様にデータ取得できます。
React×TypeScriptでプロジェクトを構築する
- コマンドプロンプトもしくはPowerShellを開いて下記を実行する
>npx create-react-app --template typescript myapp
- 動作することを確認する
>cd myapp >npm start
- ブラウザが開いて"Learn React"と表示されれば成功です。
Axiosを用いたデータ取得を実装する
- やりたいこと
GETメソッドで下記の郵便番号検索APIからデータを取得します
https://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060 - まずaxiosをインストールします
>npm install axios
- src/App.tsxのファイルを書き換える
App.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';
import axios from 'axios';
function App() {
axios.get("https://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060")
.then((results) => {
console.log(results.data);
})
.catch((error) => {
console.log('失敗');
console.log(error.status);
});
return (
<div className="App">
(変更なし。以下省略)
- F12キーを押してブラウザのデベロッパーツールのコンソールを見て郵便番号データを取得できていることを確認する。
取得したデータを画面に反映させる
さてここまででAPIからデータを取得できることがわかったのですがやはり画面上に表示させたいですよね。
「App.tsx」をこのように書き換えましょう。
App.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';
import axios from 'axios';
function App() {
const { useState, useEffect } = React;
const [message, getMessage] = useState("783-0060の都道府県は?");
useEffect(() => {
axios.get("https://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060")
.then((results) => {
console.log(results.data);
getMessage(results.data.results[0].address1);
})
.catch((error) => {
console.log('失敗');
console.log(error.status);
});
});
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
<p>{message}</p>
</header>
</div>
);
}
export default App;
- address1には都道府県名が入ります。
そこで「Learn React」の下に郵便番号「783-0060」に対応する都道府県である「高知県」と表示されれば成功です。 - 変数messageでAPIから取得したデータを保持しており、関数getMessageで変数messageのデータ更新を行っています。
- Reactのフック機能を使っています。useStateとuseEffectがキモですね。興味がある人は調べてください。
- useAxiosを使うとフックを意識することなくAPIからデータ取得できるそうな。
新しいクラスを作って画面に反映させる
Reactではコンポーネントごとに新しいクラスを作るのが基本です。
この方法でもやってみましょう。
- 新しくMyClass.tsxファイルを作成する
MyClass.tsx
import React from 'react';
import axios from 'axios';
export default class MyClass extends React.Component {
state = {message: "999-6852の都道府県は?"}
componentDidMount() {
axios.get("https://zipcloud.ibsnet.co.jp/api/search?zipcode=9996852")
.then(res => {
const mes = res.data.results[0].address1;
console.log(mes)
this.setState({message: mes});
})
}
render() {
return (
<h1>
{this.state.message}
</h1>
)
}
}
- index.tsxにMyClassを追加する
index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import MyClass from './MyClass'
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
<MyClass />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();