ReactのuseEffectについて
コンポーネントを描画と動作に分けて、描画後に表示内容の変更を行いたい時に使用する。
また、
主に、外部システムとのデータを送受信する時に使用する。
例えば、以下のコードでは入力フォームの内容に応じて、郵便番号 REST APIからデータを取得・反映させている。
import { useState, useEffect } from "react"
// メインのコンポーネント
const Post_AutoFill = () => {
// inputPostCodeという状態変数を宣言し、その初期値を空文字列に設定
const [inputPostCode, setInputPostCode] = useState("");
// addressというオブジェクトの状態変数を宣言し、その初期値を空のフィールドを持つオブジェクトに設定
const [address, setAddress] = useState({
prefecture_roman: "",
prefecture_kana: "",
prefecture: "",
city_roman: "",
city_kana: "",
city: "",
suburb_roman: "",
suburb_kana: "",
suburb: ""
});
// input要素の変更イベントハンドラ
const handleInputChange = (event) => {
setInputPostCode(event.target.value); // input要素の値をinputPostCode状態変数に設定
}
// フォームに7桁の郵便番号が入力された場合に実行されるエフェクト
// 第二引数にinputPostCodeを指定し、inputPostCodeが変更されるたびに実行される
useEffect(() => {
if (inputPostCode.length === 7) { // 郵便番号が7桁のとき
const url = `https://postcode.teraren.com/postcodes/${inputPostCode}.json`; // 郵便番号APIのURLを生成
// APIから住所情報を取得
fetch(url)
.then(response => response.json()) // レスポンスをJSON形式でパース
.then(json => {
// 取得したデータをaddress状態変数に設定
setAddress({
prefecture_roman: json.prefecture_roman,
prefecture_kana: json.prefecture_kana,
prefecture: json.prefecture,
city_roman: json.city_roman,
city_kana: json.city_kana,
city: json.city,
suburb_roman: json.suburb_roman,
suburb_kana: json.suburb_kana,
suburb: json.suburb
});
})
.catch(error => {
// エラーハンドリング
console.error("Error fetching address data:", error);
});
}
}, [inputPostCode]); // inputPostCodeが変更されるたびに実行
return (
<>
<InputArea inputPostCode={inputPostCode} onInputChange={handleInputChange} /> {/* 入力エリアのコンポーネント */}
<div className="grid gap-3"> {/* グリッドレイアウトで住所情報を表示 */}
<dl className="grid gap-1">
<dd className="text-xl">prefecture</dd>
<dd>en: {address.prefecture_roman}</dd>
<dd>kana: {address.prefecture_kana}</dd>
<dd>kanji: {address.prefecture}</dd>
</dl>
<dl className="grid gap-1">
<dd className="text-xl">city</dd>
<dd>en: {address.city_roman}</dd>
<dd>kana: {address.city_kana}</dd>
<dd>kanji: {address.city}</dd>
</dl>
<dl className="grid gap-1">
<dd className="text-xl">suburb</dd>
<dd>en: {address.suburb_roman}</dd>
<dd>kana: {address.suburb_kana}</dd>
<dd>kanji: {address.suburb}</dd>
</dl>
</div>
</>
);
}
// 入力エリアのコンポーネント
const InputArea = ({ inputPostCode, onInputChange }) => {
return (
<form className="bg-black w-fit rounded-md">
<input
className="resize-none m-2 rounded-md"
placeholder=" input post code"
value={inputPostCode} // input要素の値をinputPostCode状態変数に設定
onChange={onInputChange} // input要素の変更イベントハンドラを設定
/>
</form>
);
}