๐งโโ๏ธ
React๋ก ํผ์EtherScan API App
๋ง๋ค๋ค ์ ์ ๋ฐฐ์ ๋useEffect
์ ์ฉ๋์ ์ฐ์์ด ์๊ฐ๋์ง ์์ ์ ๋ฆฌํ๋ ๊ธ
ๅญธ่ๆ็ฟไน ไธไบฆ่ชชไน
import { useEffect } from "react";
useEffect('useEffect์ฒ๋ฆฌํ๊ณ ์ถ์ ํจ์', [React DependencyList]);
์ฒซ๋ฒ์งธ argument์๋ useEffect๋ก ์คํ์ํค๊ณ ์ถ์ ํจ์๋ฅผ,
๋๋ฒ์งธ argument์๋ react.js ๊ฐ ์ง์ผ๋ด์ผ ํ ๊ฒ์ด ๋ค์ด๊ฐ๋ค. ์ฆ, []์์ ์๋ Dependency๊ฐ ๋ณํํ ๋ react.js๊ฐ ์ฒซ๋ฒ์งธ argument์ธ ํจ์๋ฅผ ์คํ
Side Effect
: React์์ ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌ๋์ด์ง๋ ํจ์React์์ Side Effect๋ ๋นํจ์จ์ฑ์ ๋ง๋ค์ด๋ด๋๋ฐ ์ด๊ฒ์ ๋ฐ๋ก์ก์์ฃผ๊ธฐ ์ํ ๋๊ตฌ๊ฐ useEffect๋ค
์๋ฅผ ๋ค์ด, React App์์ ๋ค๋ฅธ ์ธ๋ถ ์๋ฒ๋ก API๋ฅผ ์์ฒญํ๋ฉด ๋๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ๋ค
์ฒซ ๋ฒ์งธ๋ก
, React App์ ๊ธฐ๋ณธ์ ์ผ๋ก API๋ฅผ ๊ณ์ ๋ฐ๋ณต์ ์ผ๋ก ์์ฒญํจ(๋นํจ์จ์ ์)
useEffect๋ฅผ ์ฌ์ฉํด์ ํน์ ๊ฐ์ด ๋ณํ๊ฑฐ๋(Dependency๊ฐ) ์ด๋ฒคํธ๊ฐ ์ผ์ด๋ ๋๋ง API๋ฅผ ๋ถ๋ฌ์ค๋๋ก ํ ์ ์์
๋ ๋ฒ์งธ๋ก
, ์ธ๋ถ ์๋ฒ์ ๋ฌธ์ ๊ฐ ์์ด ์์ฒญํ ๊ฐ์ ๋ฐํํ์ง ์์ React App์์ ๊ณ์ํด์ ์ธ๋ถ ์๋ฒ์ API์์ฒญ์ ์ง์์ ์ผ๋ก๋ณด๋ด๋ ๊ฒฝ์ฐ
useEffect๋ฅผ ์ฌ์ฉํด์ ๋น๋๊ธฐ ์์ฒญ์ ๋๊ธฐ์ ์ผ๋ก ์๋ฌ์ฒ๋ฆฌ ๊ฐ๋ฅํจ ๋๋ฌธ์ ์ธ๋ถ ์๋ฒ์ ๋ฌธ์ ๊ฐ ์๋๋ผ๋ ๋ถํ์ํ๊ฒ ์๋ฏธ์๋ API์์ฒญ์ ๊ณ์ํด์ ๋ณด๋ด์ง ์์
๊ทธ๋ผ ํน์ ๊ฐ์ธ Dependency๊ฐ ๋ณํ ๋๋ง useEffect๋ฅผ ์คํํด์ API๋ฅผ ์์ฒญํ ์ ์๋ค๊ณ ํ๋๋ฐ
Dependency๋ ์ด๋์ ์ ์ฅ๋์ด์ผ ํ๋๊ฐ?
import {useState } from "react";
const [data, setData] = useState('์ด๊ธฐ data๊ฐ(๋น์นธ ๊ฐ๋ฅ)');
//data์ A๊ฐ์ ์ ์ฅํ๊ณ ์ถ๋ค๋ฉด
setData(A)
console.log(data) // A
React Component
์์ ๋ณํ๋ ๊ฐ๋ค์useState
๋ฅผ ํตํด ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ค
function Account() {
const [data, setData] = useState('');
const [keyword, setKeyword] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const onChange = (event) => setKeyword(event.target.value);
async function axiosData(keyword) {
try{
// ์์ฒญ์ด ์์ ํ ๋์๋ error๋ฅผ ์ด๊ธฐํํ๊ณ
setError(null);
// loading ์ํ๋ฅผ true ๋ก ๋ฐ๊ฟ๋๋ค.
setLoading(true);
//EtherScan API์์ฒญ์ ํตํด data๋ฐ์์ด
await axios.get(`https://api-goerli.etherscan.io/api?module=account&action=balance&address=${keyword}&tag=latest&apikey='๋์ api key'`)
.then((res) => { setData(res.data); console.log(res.data); }); //useState์ setData๋ฅผ ํ์ฉํด์ data์ ์ฅ
} catch(err) { //try catch๋ฌธ์ ํตํด error์ฒ๋ฆฌ
setError(err);
}
setLoading(false);
}
//๋น๋๊ธฐ Side Effect(axios API์์ฒญ)๋ฅผ keyword๊ฐ์ด ๋ณํ ๋๋ง๋ค useEffect์ฒ๋ฆฌ
useEffect(() => {
axiosData(keyword);
}, [keyword]);
- ์ ์ฒด์ฝ๋
EtherScan API
๋ฅผ ์ด์ฉํดReact App
์์account balance
๋ฅผ ๋ฐ์์ค๊ธฐ ์ํด ์ ์ ์ฝ๋
input ํ๊ทธ์ value๊ฐ์ด(keyword
) ๋ณํ ๋๋ง(onChange
)useEffect
๋ฅผ ์ฌ์ฉํด์ axios๋ก EtherScan api๋ฅผ ์์ฒญํ๋ค
import '../App.css';
import React from 'react';
import { useEffect, useState } from "react";
import axios from 'axios';
function Account() {
const [data, setData] = useState('');
const [keyword, setKeyword] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const onChange = (event) => setKeyword(event.target.value);
async function axiosData(keyword) {
try{
// ์์ฒญ์ด ์์ ํ ๋์๋ error๋ฅผ ์ด๊ธฐํํ๊ณ
setError(null);
// loading ์ํ๋ฅผ true ๋ก ๋ฐ๊ฟ๋๋ค.
setLoading(true);
await axios.get(`https://api-goerli.etherscan.io/api?module=account&action=balance&address=${keyword}&tag=latest&apikey='๋์ api key'`)
.then((res) => { setData(res.data); console.log(res.data); });
} catch(err) {
setError(err);
}
setLoading(false);
}
//๋น๋๊ธฐ Side Effect(axios API์์ฒญ)๋ฅผ useEffect์ฒ๋ฆฌ
useEffect(() => {
axiosData(keyword);
}, [keyword]);
if (loading) return <div>Loading..</div>;
if (error) return <div>์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค</div>;
// ์์ง users๊ฐ ๋ฐ์์ ์ง์ง ์์์ ๋๋ ์๋ฌด๊ฒ๋ ํ์๋์ง ์๋๋ก ํด์ค๋๋ค.
if (!data) return null;
return(
<div>
<div className="account-menu">
<ul className="account-menu__list">
<li className="account-menu__item">
<span className="account-menu__text">
{ data.result === "Error! Invalid address format" ? <div>Please input proper account for Balance</div> : <div>{data.result/1000000000000000000} ETH</div> }
<input type="text" placeholder="Copy and paste your account.." value={keyword} onChange={onChange}/>
</span>
</li>
</ul>
</div>
</div>
)
}
export default Account;