게시판 이미지 업로드 하기
📔 결과물
💻 코드리뷰
- 일단 이미지를 넣을 수 있는 버튼을 만들어준다
map
을 이용하여 세개를 만들어 주었다.Uploads01
이란 컴포넌트를 불러왔다.<Label>사진첨부</Label> {new Array(3).fill(1).map((el, index) => ( <Uploads01 key={`${el}_${index}`} index={index} onChangeFiles={props.onChangeFiles} /> ))}
💻
Uploads01.container
... export default function Uploads01(props) { const fileRef = useRef(null); const [fileUrl, setFileUrl] = useState("");
- 클릭을 하면 파일선택창이 나오게하는 함수
function onClickUploadImage() { fileRef.current?.click(); }
- 이미지를 올리기전 파일유무, 파일용량, 파일형식에 대한 검사를 진행해준다.
async function onChangeImage(event) { const file = event.target.files[0]; if (!file) { alert("파일이 없습니다!"); return; } if (file.size > 5 * 1024 * 1024) { alert("파일 용량이 너무 큽니다. (제한: 5MB"); return; } if (!file.type.includes("jpeg") && !file.type.includes("png")) { alert("jpeg 또는 png만 업로드 가능합니다."); return; }
fileReader()
과readAsDataURL()
를 통해 임시URL
으로 변환시켜준다.- 이 임시 URL은 본인컴퓨터에서만 쓰이는
URL
이고 업로드 시에는 다시 변환시켜줘야한다.const fileReader = new FileReader(); fileReader.readAsDataURL(file); fileReader.onload = (data) => { setFileUrl(data.target?.result); props.onChangeFiles(file, props.index); }; } return ( ...)}
💻
Uploads01.presenter
import { UploadImage, UploadButton, UploadImageHidden, } from "./Uploads01.styles";
- 업로드를 위한 버튼(
UploadButton
)을 만들어주고 위에서 만든onClick
함수를 넣어준다.
- 파일
URL
을 입력하기위한 텍스트상자(UploadImageHidden
)을 만들어주고
위에서 만든onChange
함수를 넣어준다.
- 삼항연산자를 이용해서 파일
URL
이 있으면 이미지 미리보기를,
없으면 업로드버튼을 보여지게 한다.export default function Uploads01UI(props) { return ( <> {props.fileUrl ? ( <UploadImage onClick={props.onClickUploadImage} src={props.fileUrl} /> ) : ( <UploadButton onClick={props.onClickUploadImage}> <div>+</div> <div>Upload</div> </UploadButton> )} <UploadImageHidden ref={props.fileRef} type="file" onChange={props.onChangeImage} /> </> ); }
업로드를 위한 컴포넌트를 만들어줬다면 게시물 등록페이지에 import 해주고 코드를 작성해준다.
💻
New.container
... import { ... UPLOAD_FILE, } from "./New.queries";
export default function NewWrite(props) { ... const [uploadFile] = useMutation(UPLOAD_FILE); const [files, setFiles] = useState([null, null, null]);
- 파일URL이 입력되면 배열에 넣는다.
function onChangeFiles(file, index) { const newFiles = [...files]; newFiles[index] = file; setFiles(newFiles); };
- 등록하기 버튼을 누르면
map
과filter
를 사용해서Mutation
인uploadFile
을 이용해서 업로드한다.async function onClickSubmit() { ... try { const uploadFiles = files .filter((el) => el) .map((el) => uploadFile({ variables: { file: el } })); const results = await Promise.all(uploadFiles); const myImages = results.map((el) => el.data.uploadFile.url); ...
업로드를 했다면 게시물조회에서 이미지도 보여져야한다!
💻
Detail.presenter
filter
로 이미지URL
이 있는것만 이미지를 보여지게한다.
map
으로 사진있는만큼 보여지게한다.... {props.data?.fetchBoard.images ?.filter((el) => el) .map((el) => ( <Image key={el} src={`https://storage.googleapis.com/${el}`} /> ))} ...