Github API를 이용해 이미지 가져오기(react)

개발공부·2023년 4월 28일
0

React 공부하기

목록 보기
14/14

* 변경 전 프로젝트

▶ 이미지 파일들을 로컬에 저장(총 2.16MB 차지)

* 프로젝트 로컬에 이미지 파일들을 저장하면 어떤 단점이 있나요?

▶ 이미지 파일이 많아지면 로컬 저장소의 용량이 부족해질 수 있음
▶ 이미지 파일을 백업하지 않으면 데이터 손실이 발생
▶ 이미지 파일을 공유하기 어려움

* 변경 후 프로젝트

▶ React hooks을 사용
▶ Github Issues에 이미지 올린 후 해당 값의 정보를 가져옴

Github API 사용하기

  • 전제조건
    ▶ repository는 한 개 이상 생성
    ▶ issues 폴더에 이미지를 올린 후 저장해야 함

* ⑴ 깃헙의 토큰 얻기(공식사이트)

① 로그인 후 오른쪽 상단 프로필 클릭 후 Settings 누르기

② 왼쪽 사이드 바의 <> Developer settings 누르기

③ 왼쪽 사이드 바Personal access tokens -> Fine-grained token 클릭하기

④ 토큰 이름(Token name) 적고 만기일(Expiration) 설정(옵션으로 Description 기입)

⑤ 조건에 따라 레포지토리 접근(Repository access) 설정
-> 본인은 Readonly만 설정함

⑥ 생성 완료

* 참고 블로그

깃허브 링크 관련 url 주소로 가져오는 법 설명(블로그)

https://api.github.com/repos/유저이름/레포지토리이름/issues
-> 이슈 정보

https://api.github.com/repos/유저이름/레포지토리이름/languages
-> 무슨 언어 사용했는지

https://api.github.com/repos/유저이름/레포지토리이름/commits
-> 커밋 정보들

https://api.github.com/repos/유저이름/레포지토리이름/contents/pages
-> pages 안에 정보들 가져옴

⑵ github 토큰을 얻은 후 octokit/rest.js 사용

npm i @octokit/rest

⑶ 코드 작성(Hooks)

▶ 토큰은 보안을 위해 .env에 저장할 것
(.gitignore에 .env 추가)

* 과정 중 생긴 오류

React Hook "useOctokit" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function

-> 이 경우 기능 구성 요소 내부에 useOctokit 함수를 정의한 다음 useEffect 콜백 내부에서 호출한 것으로 보입니다. 그러나 React 후크는 함수 구성 요소 또는 사용자 지정 후크 함수의 최상위 수준에서만 호출할 수 있습니다.

=> useOctokit과 useLoadImg을 React Hook으로 만듦
=> useOctokit : api주소를 가져옴
=> useLoadImg : 가져온 주소에서 최종 데이터(이미지) 가져옴

[Hooks/useOctokit.js]

imgURL 콘솔값 : https://api.github.com/repos/유저이름/레포지토리/issues/2

import { useState, useEffect } from "react";
import { Octokit } from "@octokit/rest";
import axios from "axios";

const useOctokit = async () => {
  const [imgURL, setImgURL] = useState("");

  useEffect(() => {
    const fetchData = async () => {
      const octokit = new Octokit({
        auth: process.env.REACT_APP_GITHUB_API_KEY,
      });

      const result = await octokit.request("/user");
      const data = result.data;
      const repos_url = data.repos_url; //레포지토리 주소 가져옴

      try {
        const response = await axios.get(repos_url);
        
        //본인의 경우 이미지 저장한 레포지토리는 8에 위치함
        const portfolioData = response.data[8]; 
        const issue_url = portfolioData.issues_url;
        
        const img_url = issue_url.replace("{/number}", "/2");
        setImgURL(img_url);
      } catch (error) {
        console.log("error broke out:  ", error);
      }
    };
    fetchData();
  }, []);
  return imgURL;
};

export default useOctokit;

[Hooks/useLoadImg.js]

import { useState, useEffect } from "react";
import axios from "axios";

const useLoadImg = (imgURL) => {
  const [images, setImages] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get(imgURL);
        const data = response.data.body;
        const regexURL = /\(([^)]+)\)/;
        const splitImgData = data.split(regexURL);

        const result = splitImgData.filter((str) => str.startsWith("https"));
        setImages(result);
      } catch (error) {
        console.log("error broke out: ", error);
      }
    };
    fetchData();
  }, [imgURL]);

  return images;
};

export default useLoadImg;

⑷ Hooks 불러오기

[App.tsx]

import useOctokit from './Hooks/useOctokit';
import useLoadImg from './Hooks/useLoadImg';

const [data, setData] = useState([]);
  const [imgURL, setImgURL] = useState("");
  
  const rawImgURL = useOctokit();
  rawImgURL.then((value) => {
    setImgURL(value);
  });

  const findImgs = useLoadImg(imgURL);
  
  useEffect(() => {
    setData(findImgs);
  }, [findImgs])
  
  return (
  	<div>
    	{data.map((d) => (
        	<img src={d} />
        )}
    </div>
  )
profile
개발 블로그, 티스토리(https://ba-gotocode131.tistory.com/)로 갈아탐

0개의 댓글