본문 바로가기
개발/React

리액트 Material - 깃허브 리포지토리 이미지 불러오기 (Load GitHub Repository Images with Image List)

by 피로물든딸기 2024. 1. 17.
반응형

깃허브 데스크탑으로 프로젝트 관리하기 강의 오픈!! (인프런 바로가기)

 

리액트 전체 링크

Git / GitHub 전체 링크

 

참고

- https://mui.com/material-ui/react-image-list/

- RESTful API로 파일 읽기

 

깃허브 리포지토리 이미지 불러오기
깃허브 API로 이미지 업로드하기
깃허브에 업로드된 이미지 삭제하기
캡처한 이미지를 깃허브에 업로드하기
캡처한 이미지 여러 개 업로드하기
Toast UI 에디터로 이미지를 포함한 깃허브 마크다운 저장하기

 

링크를 참고하여 아래 예시 코드를 실행해 보자.

import * as React from "react";
import Box from "@mui/material/Box";
import ImageList from "@mui/material/ImageList";
import ImageListItem from "@mui/material/ImageListItem";
import ImageListItemBar from "@mui/material/ImageListItemBar";
import ListSubheader from "@mui/material/ListSubheader";
import IconButton from "@mui/material/IconButton";
import InfoIcon from "@mui/icons-material/Info";

const itemData = [
  {
    img: "https://images.unsplash.com/photo-1551963831-b3b1ca40c98e",
    title: "Breakfast",
    author: "@bkristastucchio",
  },
  {
    img: "https://images.unsplash.com/photo-1551782450-a2132b4ba21d",
    title: "Burger",
    author: "@rollelflex_graphy726",
  },
  {
    img: "https://images.unsplash.com/photo-1522770179533-24471fcdba45",
    title: "Camera",
    author: "@helloimnik",
  },
  {
    img: "https://images.unsplash.com/photo-1444418776041-9c7e33cc5a9c",
    title: "Coffee",
    author: "@nolanissac",
  },
  {
    img: "https://images.unsplash.com/photo-1533827432537-70133748f5c8",
    title: "Hats",
    author: "@hjrc33",
  },
  {
    img: "https://images.unsplash.com/photo-1558642452-9d2a7deb7f62",
    title: "Honey",
    author: "@arwinneil",
  },
  {
    img: "https://images.unsplash.com/photo-1516802273409-68526ee1bdd6",
    title: "Basketball",
    author: "@tjdragotta",
  },
  {
    img: "https://images.unsplash.com/photo-1518756131217-31eb79b20e8f",
    title: "Fern",
    author: "@katie_wasserman",
  },
  {
    img: "https://images.unsplash.com/photo-1597645587822-e99fa5d45d25",
    title: "Mushrooms",
    author: "@silverdalex",
  },
  {
    img: "https://images.unsplash.com/photo-1567306301408-9b74779a11af",
    title: "Tomato basil",
    author: "@shelleypauls",
  },
  {
    img: "https://images.unsplash.com/photo-1471357674240-e1a485acb3e1",
    title: "Sea star",
    author: "@peterlaster",
  },
  {
    img: "https://images.unsplash.com/photo-1589118949245-7d38baf380d6",
    title: "Bike",
    author: "@southside_customs",
  },
];

const ReactImageList = () => {
  return (
    <Box sx={{ m: 3 }}>
      <ImageList sx={{ width: 248 * 3 }} cols={3}>
        <ImageListItem key="Subheader" cols={3}>
          <ListSubheader component="div">GitHub Images Directory</ListSubheader>
        </ImageListItem>
        {itemData.map((item) => (
          <ImageListItem key={item.img}>
            <img
              srcSet={`${item.img}?w=248&fit=crop&auto=format&dpr=2 2x`} // 이미지 크기 조정, 자동으로 형식 지정, 필요한 경우 잘라내기(crop)
              src={`${item.img}?w=248&fit=crop&auto=format`}
              alt={item.title}
              loading="lazy" // 스크롤하여 이미지가 나타날 때, 이미지를 비동기 로딩
            />
            <ImageListItemBar
              title={item.title}
              subtitle={item.author}
              actionIcon={
                <IconButton
                  sx={{ color: "rgba(255, 255, 255, 0.54)" }}
                  aria-label={`info about ${item.title}`}
                >
                  <InfoIcon />
                </IconButton>
              }
            />
          </ImageListItem>
        ))}
      </ImageList>
    </Box>
  );
};

export default ReactImageList;

 

아래와 같이 임시 이미지들의 목록을 불러올 수 있다.


깃허브 이미지를 img 태그에 반영하기

 

깃허브 저장소의 images 폴더에 여러 이미지가 존재한다고 가정하자.

 

이미지를 클릭하면 아래와 같이 URL을 얻을 수 있다.

 

파일 이름이 image_name.jpg라면 아래와 같이 링크를 img 태그에 추가해 보자.

<img src="https://github.com/bloodstrawberry/auto-test/blob/main/imagesimage_name.jpg"/>

 

하지만 위의 링크를 그대로 사용하면 이미지를 정상적으로 불러오지 않는다.

 

정상적으로 이미지를 불러오려면, repo(auto-test)/blob/main ....에서 blob을 raw로 변경하면 된다.

<img src="https://github.com/bloodstrawberry/auto-test/raw/main/images/image_name.jpg"/>

깃허브 이미지 불러오기

 

깃허브 RESTful API를 이용하면 리포지토리에 있는 파일의 이름을 알 수 있다.

링크를 참고하여 이미지 폴더에 있는 파일의 이름을 모두 가져오자.

즉, itemData를 RESTful API를 이용하여 useState로 관리한다.

편의상 title은 이미지를 불러오는 순서대로 하고, author는 고정하였다.

import * as gh from "../githublibrary.js";

...
  
  const [itemData, setItemData] = useState([]);

  const fileLoad = async () => {
    let result = await gh.fileRead("images");
    let fileList = result.data.map((item) => item.path);

    let temp = [];
    let count = 1;
    for (let path of fileList) {
      let obj = {
        img: `https://github.com/bloodstrawberry/auto-test/raw/main/${path}`,
        title: `image_${count++}`,
        author: "bloodstrawberry",
      };

      temp.push(obj);
    }

    setItemData(temp);
  };

  useEffect(() => {
    fileLoad();
  }, []);

 

깃허브에 저장된 이미지가 정상적으로 로드된 것을 알 수 있다.

 

전체 코드는 다음과 같다.

 

githublibrary.js

import axios from "axios";
import { Octokit } from "@octokit/rest";

const myKey = process.env.REACT_APP_MY_TOKEN;
const repo = `auto-test`;

export const fileRead = async (path) => {
  try {
    const octokit = new Octokit({
      auth: myKey,
    });

    const result = await octokit.request(
      `GET /repos/bloodstrawberry/${repo}/contents/${path}`,
      {
        owner: "bloodstrawberry",
        repo: `${repo}`,
        path: `${path}`,
        encoding: "utf-8",
        decoding: "utf-8",
      }
    );
    return result;
  } catch (e) {
    console.log("error : ", e);
    return undefined;
  }
};

 

ReactImageList.js

import React, { useEffect, useState } from "react";
import Box from "@mui/material/Box";
import ImageList from "@mui/material/ImageList";
import ImageListItem from "@mui/material/ImageListItem";
import ImageListItemBar from "@mui/material/ImageListItemBar";
import ListSubheader from "@mui/material/ListSubheader";
import IconButton from "@mui/material/IconButton";
import InfoIcon from "@mui/icons-material/Info";

import * as gh from "../githublibrary.js";

const ReactImageList = () => {
  const [itemData, setItemData] = useState([]);

  const fileLoad = async () => {
    let result = await gh.fileRead("images");
    let fileList = result.data.map((item) => item.path);

    let temp = [];
    let count = 1;
    for (let path of fileList) {
      let obj = {
        img: `https://github.com/bloodstrawberry/auto-test/raw/main/${path}`,
        title: `image_${count++}`,
        author: "bloodstrawberry",
      };

      temp.push(obj);
    }

    setItemData(temp);
  };

  useEffect(() => {
    fileLoad();
  }, []);

  return (
    <Box sx={{ m: 3 }}>
      <ImageList sx={{ width: 248 * 3 }} cols={3}>
        <ImageListItem key="Subheader" cols={3}>
          <ListSubheader component="div">GitHub Images Directory</ListSubheader>
        </ImageListItem>
        {itemData.map((item) => (
          <ImageListItem key={item.img}>
            <img
              srcSet={`${item.img}?w=248&fit=crop&auto=format&dpr=2 2x`}
              src={`${item.img}?w=248&fit=crop&auto=format`}
              alt={item.title}
              loading="lazy"
            />
            <ImageListItemBar
              title={item.title}
              subtitle={item.author}
              actionIcon={
                <IconButton
                  sx={{ color: "rgba(255, 255, 255, 0.54)" }}
                  aria-label={`info about ${item.title}`}
                >
                  <InfoIcon />
                </IconButton>
              }
            />
          </ImageListItem>
        ))}
      </ImageList>
    </Box>
  );
};

export default ReactImageList;
반응형

댓글