From ddbdaf6ed30bd78d7c2b54de6e10e4b456702740 Mon Sep 17 00:00:00 2001 From: jungwoo3490 Date: Thu, 18 Jan 2024 00:51:48 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20GET=20=EB=A9=94=EC=86=8C=EB=93=9C?= =?UTF-8?q?=20React-Query=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/FavoriteImageInput/index.tsx | 60 ++++++++++++++++--- src/Target/hooks/useGetPresignedUrl.ts | 14 +++++ 2 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 src/Target/hooks/useGetPresignedUrl.ts diff --git a/src/Target/components/FavoriteImageInput/index.tsx b/src/Target/components/FavoriteImageInput/index.tsx index 917c5428..3b90fbbf 100644 --- a/src/Target/components/FavoriteImageInput/index.tsx +++ b/src/Target/components/FavoriteImageInput/index.tsx @@ -1,16 +1,51 @@ -import { useRef, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { IcCamera, ImgBook } from '../../../assets'; +import useGetPresignedUrl from '../../hooks/usegetPresignedUrl'; +import usePutPresignedUrl from '../../hooks/usePutPresignedUrl'; import * as S from './FavoriteImageInput.style'; interface FavoriteImageInputProps { - imgFile: File | null; - changeFileData: (file: File) => void; + imgFile: string; + uploadImage: (file: string) => void; + changePresignedFileName: (fileName: string) => void; } -function FavoriteImageInput({ changeFileData }: FavoriteImageInputProps) { +function FavoriteImageInput({ + imgFile, + uploadImage, + changePresignedFileName, +}: FavoriteImageInputProps) { const imgRef = useRef(null); - const [imgFile, setImgFile] = useState(''); + const [presignedData, setPresignedData] = useState({ + url: '', + fileName: '', + }); + + const { isLoading, error, data } = useGetPresignedUrl(); + const putMutation = usePutPresignedUrl(); + + useEffect(() => { + const fetchPresignedData = async () => { + if (data) { + const { url, fileName } = data; + setPresignedData({ url, fileName }); + changePresignedFileName(fileName); + } + }; + + fetchPresignedData(); + }); + + // 로딩 핸들링 + if (isLoading) { + return
로딩중
; + } + + // 에러 핸들링 + if (error) { + return
에러 발생
; + } const handleImageUpload = async (): Promise => { const fileInput = imgRef.current; @@ -22,8 +57,19 @@ function FavoriteImageInput({ changeFileData }: FavoriteImageInputProps) { base64Reader.readAsDataURL(file); base64Reader.onloadend = () => { if (base64Reader.result !== null) { - changeFileData(file); - setImgFile(base64Reader.result as string); + uploadImage(base64Reader.result as string); + } + }; + + const binaryReader = new FileReader(); + binaryReader.readAsArrayBuffer(file); + binaryReader.onloadend = async () => { + if (binaryReader.result !== null) { + putMutation.mutate({ + url: presignedData.url, + data: binaryReader.result as ArrayBuffer, + contentType: file.type, + }); } }; } diff --git a/src/Target/hooks/useGetPresignedUrl.ts b/src/Target/hooks/useGetPresignedUrl.ts new file mode 100644 index 00000000..0e4371c3 --- /dev/null +++ b/src/Target/hooks/useGetPresignedUrl.ts @@ -0,0 +1,14 @@ +import { useQuery } from 'react-query'; + +import { getPresignedUrl } from '../util/api'; + +const useGetPresignedUrl = () => { + const { isLoading, error, data } = useQuery({ + queryKey: ['get-presigned-url'], + queryFn: () => getPresignedUrl('/api/images/book'), + }); + + return { isLoading, error, data }; +}; + +export default useGetPresignedUrl; From 94d98d1e11f0e5ab21dd322362d5c652f3823d07 Mon Sep 17 00:00:00 2001 From: jungwoo3490 Date: Thu, 18 Jan 2024 04:30:50 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20PUT=20method=20react-query=20hook?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Target/hooks/usePutPresignedUrl.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/Target/hooks/usePutPresignedUrl.ts diff --git a/src/Target/hooks/usePutPresignedUrl.ts b/src/Target/hooks/usePutPresignedUrl.ts new file mode 100644 index 00000000..a316fd3f --- /dev/null +++ b/src/Target/hooks/usePutPresignedUrl.ts @@ -0,0 +1,22 @@ +import { AxiosError } from 'axios'; +import { useMutation } from 'react-query'; + +import { putPresignedUrl } from '../util/api'; + +interface putPresignedUrlProps { + url: string; + data: ArrayBuffer; + contentType: string; +} + +const usePutPresignedUrl = () => { + const mutation = useMutation({ + mutationFn: ({ url, data, contentType }: putPresignedUrlProps) => { + return putPresignedUrl(url, data, contentType); + }, + onError: (err: AxiosError) => console.log(err), + }); + return mutation; +}; + +export default usePutPresignedUrl; From b340f09133e5dcfcff66fec1a1ce25b513b7ce00 Mon Sep 17 00:00:00 2001 From: jungwoo3490 Date: Thu, 18 Jan 2024 06:42:18 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20TargetPage=20React-Query=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/FavoriteImageInput/index.tsx | 59 ++----------------- src/Target/hooks/useGetPresignedUrl.ts | 2 +- src/Target/hooks/usePutPresignedUrl.ts | 4 +- src/Target/page/TargetPage/index.tsx | 34 +++++------ src/Target/util/api.ts | 36 +++++++---- 5 files changed, 51 insertions(+), 84 deletions(-) diff --git a/src/Target/components/FavoriteImageInput/index.tsx b/src/Target/components/FavoriteImageInput/index.tsx index 3b90fbbf..f2eb5352 100644 --- a/src/Target/components/FavoriteImageInput/index.tsx +++ b/src/Target/components/FavoriteImageInput/index.tsx @@ -1,51 +1,15 @@ -import { useEffect, useRef, useState } from 'react'; +import { useRef, useState } from 'react'; import { IcCamera, ImgBook } from '../../../assets'; -import useGetPresignedUrl from '../../hooks/usegetPresignedUrl'; -import usePutPresignedUrl from '../../hooks/usePutPresignedUrl'; import * as S from './FavoriteImageInput.style'; interface FavoriteImageInputProps { - imgFile: string; - uploadImage: (file: string) => void; - changePresignedFileName: (fileName: string) => void; + changeFileData: (file: File) => void; } -function FavoriteImageInput({ - imgFile, - uploadImage, - changePresignedFileName, -}: FavoriteImageInputProps) { +function FavoriteImageInput({ changeFileData }: FavoriteImageInputProps) { const imgRef = useRef(null); - const [presignedData, setPresignedData] = useState({ - url: '', - fileName: '', - }); - - const { isLoading, error, data } = useGetPresignedUrl(); - const putMutation = usePutPresignedUrl(); - - useEffect(() => { - const fetchPresignedData = async () => { - if (data) { - const { url, fileName } = data; - setPresignedData({ url, fileName }); - changePresignedFileName(fileName); - } - }; - - fetchPresignedData(); - }); - - // 로딩 핸들링 - if (isLoading) { - return
로딩중
; - } - - // 에러 핸들링 - if (error) { - return
에러 발생
; - } + const [imgFile, setImgFile] = useState(''); const handleImageUpload = async (): Promise => { const fileInput = imgRef.current; @@ -57,19 +21,8 @@ function FavoriteImageInput({ base64Reader.readAsDataURL(file); base64Reader.onloadend = () => { if (base64Reader.result !== null) { - uploadImage(base64Reader.result as string); - } - }; - - const binaryReader = new FileReader(); - binaryReader.readAsArrayBuffer(file); - binaryReader.onloadend = async () => { - if (binaryReader.result !== null) { - putMutation.mutate({ - url: presignedData.url, - data: binaryReader.result as ArrayBuffer, - contentType: file.type, - }); + changeFileData(file); + setImgFile(base64Reader.result as string); } }; } diff --git a/src/Target/hooks/useGetPresignedUrl.ts b/src/Target/hooks/useGetPresignedUrl.ts index 0e4371c3..ce43a584 100644 --- a/src/Target/hooks/useGetPresignedUrl.ts +++ b/src/Target/hooks/useGetPresignedUrl.ts @@ -5,7 +5,7 @@ import { getPresignedUrl } from '../util/api'; const useGetPresignedUrl = () => { const { isLoading, error, data } = useQuery({ queryKey: ['get-presigned-url'], - queryFn: () => getPresignedUrl('/api/images/book'), + queryFn: () => getPresignedUrl(), }); return { isLoading, error, data }; diff --git a/src/Target/hooks/usePutPresignedUrl.ts b/src/Target/hooks/usePutPresignedUrl.ts index a316fd3f..a30c207e 100644 --- a/src/Target/hooks/usePutPresignedUrl.ts +++ b/src/Target/hooks/usePutPresignedUrl.ts @@ -3,7 +3,7 @@ import { useMutation } from 'react-query'; import { putPresignedUrl } from '../util/api'; -interface putPresignedUrlProps { +interface usePutPresignedUrlProps { url: string; data: ArrayBuffer; contentType: string; @@ -11,7 +11,7 @@ interface putPresignedUrlProps { const usePutPresignedUrl = () => { const mutation = useMutation({ - mutationFn: ({ url, data, contentType }: putPresignedUrlProps) => { + mutationFn: ({ url, data, contentType }: usePutPresignedUrlProps) => { return putPresignedUrl(url, data, contentType); }, onError: (err: AxiosError) => console.log(err), diff --git a/src/Target/page/TargetPage/index.tsx b/src/Target/page/TargetPage/index.tsx index a0b6ff7a..7818fd30 100644 --- a/src/Target/page/TargetPage/index.tsx +++ b/src/Target/page/TargetPage/index.tsx @@ -5,28 +5,31 @@ import Header from '../../../components/common/Header'; import CompleteButton from '../../components/CompleteButton'; import FavoriteImageInput from '../../components/FavoriteImageInput'; import NameInput from '../../components/NameInput'; -import { getPresignedUrl, uploadFile } from '../../util/api'; +import useGetPresignedUrl from '../../hooks/useGetPresignedUrl'; +import usePutPresignedUrl from '../../hooks/usePutPresignedUrl'; import * as S from './TargetPage.style'; function TargetPage() { const [presignedFileName, setPresignedFileName] = useState(''); const [name, setName] = useState(''); - const [fileData, setFileData] = useState(null); // Add this line + const [fileData, setFileData] = useState(null); const [presignedData, setPresignedData] = useState({ url: '', fileName: '', }); + const navigate = useNavigate(); + const { data } = useGetPresignedUrl(); + const putMutation = usePutPresignedUrl(); + useEffect(() => { - const fetchPresignedData = async () => { - const { url, fileName } = await getPresignedUrl('/api/images/book'); + if (data) { + const { url, fileName } = data; setPresignedData({ url, fileName }); setPresignedFileName(fileName); - }; - - fetchPresignedData(); - }, []); + } + }, [data]); const handleClickCompleteButton = async () => { if (fileData) { @@ -34,11 +37,11 @@ function TargetPage() { reader.readAsArrayBuffer(fileData); reader.onloadend = async () => { if (reader.result !== null) { - await uploadFile( - presignedData.url, - reader.result as ArrayBuffer, - fileData.type, - ); + putMutation.mutate({ + url: presignedData.url, + data: reader.result as ArrayBuffer, + contentType: fileData.type, + }); } }; } @@ -59,10 +62,7 @@ function TargetPage() { 최애의 사진 업로드 - setFileData(file)} - /> + setFileData(file)} /> { + // const { data } = await api.get('/api/images/note'); + // return data; + // }; + + // export default getPresignedUrl; } -const getPresignedUrl = async ( - endpoint: string, -): Promise<{ url: string; fileName: string }> => { - const response: AxiosResponse = await api.get(endpoint); +const getPresignedUrl = async (): Promise<{ + url: string; + fileName: string; +}> => { + const response: AxiosResponse = + await api.get('/api/images/book'); + console.log(response); return { url: response.data.data.url, fileName: response.data.data.fileName, }; }; -const uploadFile = async ( +const putPresignedUrl = async ( url: string, data: ArrayBuffer, contentType: string, ): Promise => { - await api.put(url, data, { - headers: { - 'Content-Type': contentType, - }, - }); + await api + .put(url, data, { + headers: { + 'Content-Type': contentType, + }, + }) + .then((res) => { + console.log(res); + }); }; -export { getPresignedUrl, uploadFile }; +export { getPresignedUrl, putPresignedUrl }; From a056556c290ea766ab35289faef4a5eb7e0ca3e3 Mon Sep 17 00:00:00 2001 From: jungwoo3490 Date: Thu, 18 Jan 2024 06:45:27 +0900 Subject: [PATCH 4/6] =?UTF-8?q?chore:=20prop=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Target/hooks/usePutPresignedUrl.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Target/hooks/usePutPresignedUrl.ts b/src/Target/hooks/usePutPresignedUrl.ts index a30c207e..a316fd3f 100644 --- a/src/Target/hooks/usePutPresignedUrl.ts +++ b/src/Target/hooks/usePutPresignedUrl.ts @@ -3,7 +3,7 @@ import { useMutation } from 'react-query'; import { putPresignedUrl } from '../util/api'; -interface usePutPresignedUrlProps { +interface putPresignedUrlProps { url: string; data: ArrayBuffer; contentType: string; @@ -11,7 +11,7 @@ interface usePutPresignedUrlProps { const usePutPresignedUrl = () => { const mutation = useMutation({ - mutationFn: ({ url, data, contentType }: usePutPresignedUrlProps) => { + mutationFn: ({ url, data, contentType }: putPresignedUrlProps) => { return putPresignedUrl(url, data, contentType); }, onError: (err: AxiosError) => console.log(err), From 94a9f235df584f7088b4ffeeeefca140b9dc17b1 Mon Sep 17 00:00:00 2001 From: jungwoo3490 Date: Thu, 18 Jan 2024 06:53:36 +0900 Subject: [PATCH 5/6] src/Target --- src/Target/util/api.ts | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/Target/util/api.ts b/src/Target/util/api.ts index d06c3b8e..6db7b0b3 100644 --- a/src/Target/util/api.ts +++ b/src/Target/util/api.ts @@ -7,13 +7,6 @@ interface PresignedUrlResponse { url: string; fileName: string; }; - - // const getPresignedUrl = async () => { - // const { data } = await api.get('/api/images/note'); - // return data; - // }; - - // export default getPresignedUrl; } const getPresignedUrl = async (): Promise<{ @@ -22,7 +15,6 @@ const getPresignedUrl = async (): Promise<{ }> => { const response: AxiosResponse = await api.get('/api/images/book'); - console.log(response); return { url: response.data.data.url, fileName: response.data.data.fileName, @@ -34,15 +26,11 @@ const putPresignedUrl = async ( data: ArrayBuffer, contentType: string, ): Promise => { - await api - .put(url, data, { - headers: { - 'Content-Type': contentType, - }, - }) - .then((res) => { - console.log(res); - }); + await api.put(url, data, { + headers: { + 'Content-Type': contentType, + }, + }); }; export { getPresignedUrl, putPresignedUrl }; From 710b015b0bfe8a1fbc65519c5d88eb48ad911adc Mon Sep 17 00:00:00 2001 From: jungwoo3490 Date: Thu, 18 Jan 2024 06:54:25 +0900 Subject: [PATCH 6/6] =?UTF-8?q?Revert=20"chore:=20prop=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=88=98=EC=A0=95"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit a056556c290ea766ab35289faef4a5eb7e0ca3e3. --- src/Target/hooks/usePutPresignedUrl.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Target/hooks/usePutPresignedUrl.ts b/src/Target/hooks/usePutPresignedUrl.ts index a316fd3f..a30c207e 100644 --- a/src/Target/hooks/usePutPresignedUrl.ts +++ b/src/Target/hooks/usePutPresignedUrl.ts @@ -3,7 +3,7 @@ import { useMutation } from 'react-query'; import { putPresignedUrl } from '../util/api'; -interface putPresignedUrlProps { +interface usePutPresignedUrlProps { url: string; data: ArrayBuffer; contentType: string; @@ -11,7 +11,7 @@ interface putPresignedUrlProps { const usePutPresignedUrl = () => { const mutation = useMutation({ - mutationFn: ({ url, data, contentType }: putPresignedUrlProps) => { + mutationFn: ({ url, data, contentType }: usePutPresignedUrlProps) => { return putPresignedUrl(url, data, contentType); }, onError: (err: AxiosError) => console.log(err),