오늘의 목표
1. 기존이미지 비효율적 FileReader
2. Async-await에 for문을 안써야 한다? promise all
3. 이미지를 내가 원할 때 불러올수 있음 LazyLoad/preLoad
import { gql, useMutation } from "@apollo/client";
import { ChangeEvent, useState } from "react";
const UPLOAD_FILE = gql`
mutation uploadFile($file: Upload!) {
uploadFile(file: $file) {
# 결과
url
}
}
`;
export const CREATE_BOARD = gql`
mutation createBoard($createBoardInput: CreateBoardInput!) {
createBoard(createBoardInput: $createBoardInput) {
_id
}
}
`;
export default function ImageUploadPreviewPage() {
const [imageUrl, setImageUrl] = useState("");
const [uploadFile] = useMutation(UPLOAD_FILE);
const [createBoard] = useMutation(CREATE_BOARD);
const [file1, setFile1] = useState<File>();
const onChangeFile = (event: ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file) {
alert("파일이 없습니다.");
return;
}
// 기존 내장함수
const fileReader = new FileReader();
// 파일url로 읽어들임
fileReader.readAsDataURL(file);
fileReader.onload = (data) => {
// data.target.result가 string 타입일 때만
if (typeof data.target?.result === "string") {
console.log(data.target?.result);
// 문자형태로 파일을 읽은 결과물
setImageUrl(data.target?.result);
setFile1(file);
}
};
};
const onClickSubmit = async () => {
const result1 = await uploadFile({
variables: { file: file1 },
});
const imageUrl = result1.data.uploadFile.url;
const result2 = await createBoard({
variables: {
createBoardInput: {
writer: "영희",
password: "1234",
title: "안녕하세요",
contents: "이미지업로드입니다.",
images: [imageUrl],
},
},
});
console.log(result2.data.createBoard._id);
};
return (
<div>
<input type="file" onChange={onChangeFile} />
<img src={imageUrl} />
<button onClick={onClickSubmit}>게시글 등록하기</button>
</div>
);
}
export default function PromiseAllPage() {
const onClickPromise = async () => {
// 시간 체크 방법
performance.now();
console.time("Promise 시작");
const result1 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve("https://dog1.jpg");
}, 3000);
});
console.log(result1);
const result2 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve("https://dog2.jpg");
}, 1000);
});
console.log(result2);
const result3 = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve("https://dog3.jpg");
}, 2000);
});
console.log(result3);
// 시간 체크 방법
console.timeEnd("Promise 시작");
};
const onClickPromiseAll = async () => {
// 1. 하나하니씩 확인하는 방법
// console.time("PromiseAll시작");
// const result = await Promise.all([
// new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve("https://dog1.jpg");
// }, 3000);
// }),
// new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve("https://dog2.jpg");
// }, 3000);
// }),
// new Promise((resolve, reject) => {
// setTimeout(() => {
// resolve("https://dog3.jpg");
// }, 3000);
// }),
// ]);
// // result = ["https://dog1.jpg", "https://dog2.jpg", "https://dog3.jpg"] 로 된다
// console.log(result);
// console.timeEnd("PromiseAll시작");
// 2. 한번에 확인하는 방법
console.time("PromiseAll시작");
const result = await Promise.all(
["https://dog1.jpg", "https://dog2.jpg", "https://dog3.jpg"].map(
(el) =>
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(el);
}, 3000);
})
)
);
console.log(result);
console.timeEnd("PromiseAll시작");
};
return (
<div>
<button onClick={onClickPromise}>Promise 연습하기</button>
<button onClick={onClickPromiseAll}>Promise.All 연습하기</button>
</div>
);
}
lazyload 스크롤 내리면서 조금씩 다운로드
라이브러리 사용
preload 다른곳으로 넘어가려고 하는데 다른 메뉴에 있을 때 사전에 다운로드 받아놓는 방식
react-dropzone 이미지 드롭
react-avatar-editor 사진 편집하는 기능
react-beautiful-dnd 사진 드래그앤드롭 기능
google page speed insights 홈페이지 속도 측정 기능