Skip to content

Commit

Permalink
refactor: useList 개선, useFetch훅 추가
Browse files Browse the repository at this point in the history
- 좀더 범용적이고, 재사용하기 좋은 데이터 패칭 훅을 고려
- 리스트형 데이터에 특화된 useList의 장점은 살려둠
  • Loading branch information
cksrlcks committed Nov 29, 2024
1 parent bf2d40b commit fd6c04e
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 18 deletions.
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,33 @@ state 관리하고 있는 params과 usePageSize로 관리하는 pageSize의 변
- useList에서 보정을 하려면, pagination 훅에서 관리하는 값을 가져와야했고,
- usePageSize에서 보정을 하려면 List컴포넌트에서 관리하고 있는 params state의 정보와 관리하는 함수들을 가져와야했습니다.
- 최종적으로 내린 결론은, 통신쪽을 수정하여 이전 요청을 취소하고 통신을 하는 방향으로 수정을 했습니다.

#### useList vs useFetch

데이터를 받는 훅을 만들때, 처음에는 리스트에 특화된 훅을 만드려고 했는데 다른곳에서는 재사용하기 힘들어서
범용적인 데이터를 받는 훅을 만드는게 좋을것 같아서 고민을 했습니다.

1. 첫번째 시도(기존코드) (리스트형 데이터 패칭에 특화된 useList)

- 장점

- useList를 호출할때 넣어야되는 필요로하는 인자가 정해져 있어서 편리(눈에 잘보임)
- params 객체를 넘겨받아도 인자가 정해져있으니 구조분해하여 useEffect의 의존성배열에 넣기 수월

- 단점
- 하지만 모든 요청에 동일한 인자를 보내는건 아니므로 범용성이 떨어져보임
- 좀더 일반적인 함수로 바꿔보려고 두번째 시도인 useFetch를 생각

2. 두번째 시도 (데이터요청함수를 실행만 하고 그 함수에 보낼 인자들을 넘겨주기만 하는 useFetch)

- 장점
- 훅 자체는 요청함수, 인자들에대해 모르고 있어도 되어서 범용성이 좋은것 같음
- 단점
- 그대신 넘어가는 인자들을 객체로 보내는데 useMemo로 참조를 보정해줘야함(어떤게 올지 몰라서, 구조분해로 분리못함)
- 그리고 무슨 인자로 요청하는지는 파악이 안됨 (사용하는 입장에서)

3. 세번째 시도 (둘다 이용해볼까?)

- useList가 useFetch를 이용하면 안될까? 필요한곳에서 useFetch를 재사용도 가능짐
- useList가 받은 객체를 메모지이에션해서 useFetch로 넘겨주는 방식으로 작업했습니다.
- 효과 : useList에서 받아야하는 인자값을 나타낼수 있고, useFetch를 useList 뿐만 아니라 다른곳에서도 사용 가능
41 changes: 41 additions & 0 deletions src/hooks/useFetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useEffect, useState } from "react";

export default function useFetch(fetchFn, params) {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);

useEffect(() => {
const abortcontroller = new AbortController();
const signal = abortcontroller.signal;

(async function getData() {
try {
setError(null);
setIsLoading(true);

const res = await fetchFn(params, { signal });

setData(res);

return res;
} catch (err) {
if (err.name !== "AbortError") {
setError(err);
}
} finally {
setIsLoading(false);
}
})();

return () => {
abortcontroller.abort();
};
}, [fetchFn, params]);

return {
isLoading,
error,
data,
};
}
28 changes: 10 additions & 18 deletions src/hooks/useList.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
import { useEffect } from "react";
import useAsync from "@hooks/useAsync";
import { useMemo } from "react";
import useFetch from "./useFetch";

export default function useList(fetchFn, params) {
const { page, pageSize, keyword, orderBy } = params;
const { isLoading, error, result, wrappedFn: getData } = useAsync(fetchFn);
const items = result?.list || [];
const totalCount = result?.totalCount || 0;

useEffect(() => {
(async function fetchData() {
await getData({
page,
pageSize,
keyword,
orderBy,
});
})();
}, [page, pageSize, keyword, orderBy]);
export default function useList(fetchFn, { page, pageSize, keyword, orderBy }) {
const memoParams = useMemo(
() => ({ page, pageSize, keyword, orderBy }),
[page, pageSize, keyword, orderBy]
);
const { isLoading, error, data } = useFetch(fetchFn, memoParams);
const items = data?.list || [];
const totalCount = data?.totalCount || 0;

return {
isLoading,
Expand Down
19 changes: 19 additions & 0 deletions src/pages/items/AllItemsPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,25 @@ export default function AllItemsPage() {
});
const { keyword, orderBy, page } = params;
const { pageSize } = usePageSize(rspnSize);

// useList vs useFetch
//
// 1) 첫번째 시도 (리스트형 데이터 패칭에 특화된 useList)
// 장점 : useList를 호출할때 넣어야되는 필요로하는 인자가 정해져 있어서 편리
// params 객체를 넘겨받아도 인자가 정해져있으니 구조분해하여 useEffect의 의존성배열에 넣기 수월
// 단점 : 하지만 모든 요청에 동일한 인자를 보내는건 아니므로 범용성이 떨어져보임, 좀더 일반적인 함수로 바꿔보려고 두번째 시도인 useFetch를 생각
//
// 2) 두번째 시도 (데이터요청함수를 실행만 하고 그 함수에 보낼 인자들을 넘겨주기만 하는 useFetch)
// 장점 : 훅 자체는 요청함수, 인자들에대해 모르고 있어도 되어서 범용성이 좋은것 같음
// 단점 : 그대신 넘어가는 인자들을 객체로 보내는데 useMemo로 참조를 보정해줘야함(어떤게 올지 몰라서, 구조분해로 분리못함)
// 그리고 무슨 인자로 요청하는지는 파악이 안됨
//
// 3) 세번째 시도 (두개를 다 쓰자!!)
// useList가 useFetch를 내부적으로 쓰면되자나
// useList가 받은 객체를 메모지이에션해서 useFetch로 넘겨주는 방식으로
// 효과 : useList에서 받아야하는 인자값을 나타낼수 있고,
// useFetch를 useList 뿐만 아니라 다른곳에서도 사용 가능

const { isLoading, error, items, totalCount } = useList(getProducts, {
page,
pageSize,
Expand Down

0 comments on commit fd6c04e

Please sign in to comment.