-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat: #63 useAxios 트리거 형태로 변경 & API 함수 구조 변경
- Loading branch information
Showing
2 changed files
with
51 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,55 @@ | ||
import axios from 'axios'; | ||
import { useEffect, useState } from 'react'; | ||
|
||
import { useState, useCallback } from 'react'; | ||
import type { AxiosResponse } from 'axios'; | ||
|
||
type PromiseCallback<T, P extends unknown[]> = (signal: AbortSignal, ...params: P) => Promise<AxiosResponse<T>>; | ||
type PromiseCallback<T, P extends unknown[]> = (...args: P) => Promise<AxiosResponse<T>>; | ||
|
||
export default function useAxios<T, P extends unknown[]>(fetchCallback: PromiseCallback<T, P>, ...params: P) { | ||
/** | ||
* Axios API 함수를 처리하는 커스텀 훅 | ||
* | ||
* @export | ||
* @template T - AxiosResponse의 응답 데이터 타입 | ||
* @template {unknown[]} P - API 함수에 전달되는 매개변수의 가변인자 타입 배열 | ||
* @param {PromiseCallback<T, P>} fetchCallback - API 요청을 수행하는 함수 | ||
* @returns {{ | ||
* data: T | undefined; // API 요청의 응답 데이터 | ||
* error: Error | null; // API 요청 중 발생한 에러 | ||
* loading: boolean; // 데이터 로딩 중인지 여부 | ||
* fetchData: (...args: P) => Promise<void>; // API 요청을 호출하는 함수 | ||
* }} | ||
* @example | ||
* const { data, error, loading, fetchData } = useAxios(fetchCallback) // fetchCallback에서 타입을 반환한다면, 자동 타입 추론이 가능 | ||
* const { data, error, loading, fetchData } = useAxios<User[], Parameters<typeof fetchCallback>>(fetchCallback); | ||
*/ | ||
export default function useAxios<T, P extends unknown[]>(fetchCallback: PromiseCallback<T, P>) { | ||
const [data, setData] = useState<T>(); | ||
const [error, setError] = useState<Error | null>(null); | ||
const [loading, setLoading] = useState(false); | ||
|
||
// ToDo: 성공/실패 토스트 메세지 출력하기 | ||
useEffect(() => { | ||
const fetchController = new AbortController(); | ||
const { signal } = fetchController; | ||
|
||
const fetch = async () => { | ||
const fetchData = useCallback( | ||
async (...params: P) => { | ||
try { | ||
setLoading(true); | ||
const response = await fetchCallback(signal, ...params); | ||
const response = await fetchCallback(...params); | ||
setData(response.data); | ||
} catch (error: unknown) { | ||
if (axios.isAxiosError(error)) { | ||
if (error.request) { | ||
// ToDo: 네트워크 요청을 보냈지만 응답이 없는 경우 에러 처리 | ||
} else if (error.response) { | ||
// ToDo: 요청후 응답을 받았지만 200 이외의 응답 코드인 경우 예외 처리 | ||
} else { | ||
// ToDo: 그 외 예외 처리 | ||
} | ||
setError(error as Error); | ||
|
||
if (!axios.isAxiosError(error)) return; | ||
|
||
if (error.request) { | ||
// ToDo: 네트워크 요청을 보냈지만 응답이 없는 경우 에러 처리 | ||
} else if (error.response) { | ||
// ToDo: 요청후 응답을 받았지만 200 이외의 응답 코드인 경우 예외 처리 | ||
} else { | ||
// ToDo: request 설정 오류 | ||
} | ||
} finally { | ||
if (!signal.aborted) setLoading(false); | ||
setLoading(false); | ||
} | ||
}; | ||
fetch(); | ||
|
||
return () => { | ||
fetchController.abort(); | ||
}; | ||
}, [fetchCallback, params]); | ||
}, | ||
[fetchCallback], | ||
); | ||
|
||
return { data, loading }; | ||
return { data, error, loading, fetchData }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,22 @@ | ||
import { authAxios } from '@services/axiosProvider'; | ||
|
||
import type { AxiosRequestConfig } from 'axios'; | ||
import type { User } from '@/types/UserType'; | ||
import type { Project } from '@/types/ProjectType'; | ||
|
||
/** | ||
* 프로젝트에 속한 유저 목록을 검색하는 API | ||
* | ||
* @export | ||
* @async | ||
* @param {Project['projectId']} projectId - 프로젝트 아이디 | ||
* @param {User['nickname']} nickname - 유저 닉네임 | ||
* @param {AxiosRequestConfig} [axiosConfig={}] - axios 요청 옵션 설정 객체 | ||
* @returns {Promise<AxiosResponse<User[]>>} | ||
*/ | ||
export async function findUserByProject( | ||
signal: AbortSignal | null, | ||
projectId: Project['projectId'], | ||
nickname: User['nickname'], | ||
axiosConfig: AxiosRequestConfig = {}, | ||
) { | ||
const axiosConfig = signal ? { signal } : {}; | ||
return authAxios.get<User[]>(`project/${projectId}/user/search?nickname=${nickname}`, axiosConfig); | ||
} |