-파일을 선택하면 이미지를 추가할 수 있게 개발
-이미지 삭제 기능 추가
-반응형으로 개발하여 화면이 작아지면 좌우로 스크롤하여 이미지를 볼 수 있는 기능 추가


React 프로젝트 생성

그냥 리액트를 사용하게 되면 따로 리액트, 리액트 돔, 번들러, 바벨 등등을 일일이 설치해야되기 때문에
create react-app 설치 권장

$ npm i -g yarn
$ yarn create react-app image-gallery[폴더명] --template typescript

이미지 갤러리 로직 구현하기

-버튼을 클릭하면 이미지 파일을 드래그해서 내려받을 수 있고 삭제할 수 있는 가능 구현
-이미지 박스들은 무한히 늘어날 수 있다. [이미지를 계속 추가할 수 있기 때문]

*이미지가 들어갈 컴포넌트 만들기

// src/components/ImageBox.tsx

//타입스크립트 문법으로 props의 타입을 정해준다.[props는 기본적으로 오브젝트여야함 {}]
function ImageBox(props: { src: string }) {
    return (
        <div className="image-box">
            {/* 이미지를 받을 수 있게 기능 구현 */}
            <img src={props.src} />
        </div>
    );
}

//해당 함수를 다른 곳에서 사용할 것이니까 export를 통해 내보내준다.
export default ImageBox;

*이미지 렌더링

// App.tsx

import React, { useRef, useState } from "react";
import "./App.css";
import ImageBox from "./components/ImageBox";

function App() {
  const inpRef = useRef<HTMLInputElement>(null);
  const [imageList, setImageList] = useState<string[]>([]);

  console.log(imageList);

  return (
    <div className="container">
      <div className={"gallery-box" + (imageList.length > 0 && "row")}>
        {imageList.length === 0 && (
          <div className="text-center">
            이미지가 없습니다. <br />
            이미지를 추가해주세요.
          </div>
        )}
        <input
          type="file"
          ref={inpRef}
          onChange={(event) => {
            if (event.currentTarget.files?.[0]) {
              const file = event.currentTarget.files[0];

              console.log(file.name);

              //파일을 이미지 url로 바꿔주기
              const reader = new FileReader();
              reader.readAsDataURL(file);
              reader.onloadend = (event) => {
                setImageList((prev) => [
                  ...prev,
                  event.target?.result as string,
                ]);
              };
            }
          }}
        />
        {imageList.map((el, idx) => (
          <ImageBox key={el + idx} src={el} />
        ))}
        <div
          className="puls-box mt"
          onClick={() => {
            inpRef.current?.click();
          }}
        >
          +
        </div>
      </div>
    </div>
  );
}

export default App;

드래그 드롭 사용하여 UX 개선하기

react-dropzone 라이브러리를 사용하여 드래그 드롭 기능 구현

$ yarn add react-dropzone
$ yarn add @types/react-dropzone

파일을 클릭해서 넣는 것이 아닌 폴더에서 드래그 앤 드롭으로 이미지 추가 가능하게 구현

// App.tsx

import React, { useCallback, useRef, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import './App.css';
import ImageBox from './components/ImageBox';


function App() {
	const [imageList, setImageList] = useState<string[]>([])

	const onDrop = useCallback(acceptedFiles => {
		console.log(acceptedFiles)
		if (acceptedFiles.length) {


			for (const file of acceptedFiles) {
				const reader = new FileReader();

				reader.readAsDataURL(file)
				reader.onloadend = (event) => {
					setImageList(prev => [...prev, event.target?.result as string])
				}
			}
		}
	}, [])

	const { getRootProps, getInputProps } = useDropzone({ onDrop })


	return (
		<div className='container'>
			<div className={'gallery-box ' + (imageList.length > 0 && 'row')}>
				{
					imageList.length === 0 &&
					<div className='text-center'>
						이미지가 없습니다.<br />
						이미지를 추가해주세요.
					</div>
				}
				{
					imageList.map((el, idx) => <ImageBox key={el + idx} src={el} />)
				}
				<div className='plus-box'
					{...getRootProps()}
				>
					<input
						{...getInputProps()}
					/>
					+
				</div>
			</div>
		</div>
	);
}

export default App;
profile
Frontend Developer / Amateur Designer

0개의 댓글