App.tsx
App.css
참고자료 & 더 알아볼 자료
+ 버튼
에 이미지를 드래그 드롭 시 이미지가 자동 첨부되어 갤러리에 리스팅되도록 구현
react-dropzone
https://react-dropzone.js.org/
JS로 된 라이브러리를 TS 지원하도록 설치 (add @types/)
yarn add @types/react-dropzone
import {useDropzone} from 'react-dropzone'
useCallback, useDropzone hook 활용 (import)
onDrop 함수를 통해서 파일을 수락
기본 코드를 활용해서 이미지 갤러리에 구현
import React, {useCallback} from 'react'
import {useDropzone} from 'react-dropzone'
function MyDropzone() {
const onDrop = useCallback(acceptedFiles => {
// Do something with the files
}, [])
const {getRootProps, getInputProps, isDragActive} = useDropzone({onDrop})
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
{
isDragActive ?
<p>Drop the files here ...</p> :
<p>Drag 'n' drop some files here, or click to select files</p>
}
</div>
)
}
import React, { useState, useCallback } from 'react';
import './App.css';
import ImageBox from './components/ImageBox';
import { useDropzone } from 'react-dropzone'
function App() {
const [imageList, setImageList] = useState<string[]>([]);
const onDrop = useCallback((acceptedFiles: any) => {
console.log(acceptedFiles)
if(acceptedFiles.length){
for(const file of acceptedFiles) {
// const file = event.currentTarget.files[0];
// console.log(file.name)
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 && 'true')}>
<input type="file"
{...getInputProps()}
/>
<div className="plus--btn"
{...getRootProps()}
>
+
</div>
{ imageList.length === 0 &&
<div className="no--case">
<span className="title">이미지가 없습니다.</span><br />
<span className="text">이미지를 추가해주세요.</span>
</div>
}
</div>
{
imageList.map((el, idx)=><ImageBox key={el + idx} src={el} alt="" />)
}
</div>
);
}
export default App;
- 버튼
(삭제버튼)을 만들어서 삭제 버튼 클릭 시 갤러리에서 이미지가 삭제되는 removeFile 추가참고자료
App.tsx
import React, { useState, useCallback } from 'react';
import './App.css';
import ImageBox from './components/ImageBox';
import { useDropzone } from 'react-dropzone'
function App() {
const [imageList, setImageList] = useState<string[]>([]);
...
const removeFile = (file: any) => {
if (window.confirm("정말 삭제하시겠습니까?")) {
const newFiles = [...imageList]
newFiles.splice(newFiles.indexOf(file.name), 1)
setImageList(newFiles)
}
}
return (
<div className="container">
<div className={'gallery--box ' + (imageList.length > 0 && 'true')}>
<input type="file" {...getInputProps()} />
<div className="plus--btn" {...getRootProps()}>+</div>
{ imageList.length === 0 &&
<div className="no--case">
<span className="title">이미지가 없습니다.</span><br />
<span className="text">이미지를 추가해주세요.</span>
</div>
}
</div>
{
imageList.map((el, idx)=>
<div key={el + idx} className="gallery--list">
<ImageBox src={el} alt="" />
<div className="minus--btn" onClick={()=>removeFile(el)}>-</div>
</div>
)
}
</div>
);
}
중간에 코드 바꿈 + 강의에 없는 내용(삭제) 추가 등으로 조금 내용이 뒤죽박죽.. (드래그될때 탐색기가 안보여서 드래그과정이 안 보이게 캡처되서 아쉽)