見出し画像

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>
    );
}

この記事が気に入ったらサポートをしてみませんか?