React - useEffect

Hong·2022년 12월 21일
0




🧔‍♂️
React로 혼자 EtherScan API App만들다 전에 배웠던 useEffect의 용도와 쓰임이 생각나지 않아 정리하는 글
學而時習之 不亦說乎




⚛️ useEffect

import { useEffect } from "react";

useEffect('useEffect처리하고 싶은 함수', [React DependencyList]);

첫번째 argument에는 useEffect로 실행시키고 싶은 함수를,
두번째 argument에는 react.js 가 지켜봐야 할 것이 들어간다. 즉, []안에 있는 Dependency가 변화할때 react.js가 첫번째 argument인 함수를 실행




💥 side Effect, useState

useEffect를 위해서는 side Effect와 useState를 알아야한다


  • Side Effect

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는 어디에 저장되어야 하는가?


  • useState
import {useState } from "react";

const [data, setData] = useState('초기 data값(빈칸 가능)');

//data에 A값을 저장하고 싶다면
setData(A)
console.log(data) // A

React Component에서 변하는 값들은 useState를 통해 저장하고 관리한다




실제 useEffect사용한 부분

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




🍌 account.js

  • 전체코드

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;
profile
Notorious

0개의 댓글