-
Notifications
You must be signed in to change notification settings - Fork 0
[REFACTOR] IPC 함수 고도화 #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
열린토론대회 예선/본선 및 결선 데이터 2건 추가
- 최초 실행 시 열린토론대회 데이터 2건 추가 - 화면 크기 및 아이콘 설정 - 일부 에셋 및 파일 경로를 빌드 설정에 따라 명확하게 지정
|
""" Walkthrough이 변경사항은 토론 테이블 데이터 구조에 Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI
participant useAsyncRequest
participant Repository
participant API (electron)
participant FileSystem
User->>UI: 페이지 진입/버튼 클릭
UI->>useAsyncRequest: execute(요청)
useAsyncRequest->>Repository: API 함수 호출
Repository->>API (electron): IPC 요청 (예: getAllItems, postItem)
API (electron)->>FileSystem: 파일 읽기/쓰기
FileSystem-->>API (electron): 데이터 반환
API (electron)-->>Repository: 결과 반환 (datetime 포함)
Repository-->>useAsyncRequest: 데이터/에러 반환
useAsyncRequest-->>UI: isLoading/data/error 상태 업데이트
UI-->>User: 로딩/에러/성공 UI 표시
Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Suggested reviewers
Poem
""" Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
npm error Exit handler never called! 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
♻️ Duplicate comments (2)
src/constants/sample_table.ts (2)
84-84: 샘플 데이터의 datetime 필드 값 검토 필요OPEN_DEBATE_MAIN_ROUND에서도 동일한 빈 문자열 datetime 필드 문제가 있습니다.
153-153: 샘플 데이터의 datetime 필드 값 검토 필요OPEN_DEBATE_FINAL_ROUND에서도 동일한 빈 문자열 datetime 필드 문제가 있습니다.
🧹 Nitpick comments (9)
src/components/async/ErrorIndicator.tsx (2)
17-24: 접근성 개선 제안재시도 버튼의 접근성을 향상시키기 위한 개선사항을 제안합니다:
{onClickRetry && ( <button onClick={() => onClickRetry()} className="small-button enabled px-8 py-1" + aria-label="데이터 로딩 재시도" + type="button" > 다시 시도하기 </button> )}
aria-label을 추가하여 스크린 리더 사용자에게 명확한 정보 제공type="button"을 명시하여 의도를 명확히 함
13-15: 아이콘 접근성 개선 제안에러 아이콘에 접근성 속성을 추가하여 스크린 리더 사용자에게 더 나은 경험을 제공할 수 있습니다:
- <MdErrorOutline className="size-32 text-red-500" /> + <MdErrorOutline + className="size-32 text-red-500" + aria-label="오류 아이콘" + role="img" + />src/constants/formats.ts (1)
1-1: 날짜 포맷 상수 정의 검토DATETIME_FORMAT 상수가 적절히 정의되었습니다. luxon 라이브러리와 호환되는 형식입니다.
더 나은 타입 안전성과 문서화를 위해 다음과 같이 개선할 수 있습니다:
-export const DATETIME_FORMAT: string = 'yyyy-MM-dd HH:mm:ss'; +/** + * 애플리케이션 전체에서 사용할 날짜-시간 포맷 + * luxon 라이브러리와 호환되는 형식 + * @example '2024-01-15 14:30:25' + */ +export const DATETIME_FORMAT = 'yyyy-MM-dd HH:mm:ss' as const;
- JSDoc 주석으로 용도와 예시 제공
as const를 사용하여 리터럴 타입으로 추론src/type/type.ts (1)
44-44: 타입 정의가 올바르게 추가되었습니다.
datetime필드가DebateInfo인터페이스에 적절히 추가되었으며, 다른 파일들과의 타입 일관성을 유지하고 있습니다.더 나은 개발자 경험을 위해 JSDoc 주석으로 필드의 목적과 형식을 문서화하는 것을 고려해보세요:
export interface DebateInfo { id: UUID; + /** 토론 생성 날짜 및 시간 (yyyy-MM-dd HH:mm:ss 형식) */ datetime: string; name: string; agenda: string; prosTeamName: string; consTeamName: string; warningBell: boolean; finishBell: boolean; }src/page/TableComposition/TableComposition.test.tsx (1)
93-95: 테스트 데이터가 실제 사용 패턴과 일치하도록 개선되었습니다.
tableId를 UUID 형식으로 변경하여 타입 시스템과 일치시킨 것은 좋은 개선사항입니다.테스트 가독성을 위해 하드코딩된 UUID를 상수로 정의하는 것을 고려해보세요:
+const TEST_TABLE_ID = '79800bb7-70a1-4564-b790-e2148967af7e'; + it('Modification flow test', async () => { render( <TestWrapper initialEntries={[ - '/composition?mode=edit&tableId=79800bb7-70a1-4564-b790-e2148967af7e&mode=CUSTOMIZE', + `/composition?mode=edit&tableId=${TEST_TABLE_ID}&mode=CUSTOMIZE`, ]} > <TableComposition /> </TestWrapper>, );electron/constants.ts (1)
3-3: 날짜/시간 형식 상수가 적절히 정의되었습니다.
DATETIME_FORMAT상수를 정의하여 날짜 형식의 일관성을 보장한 것은 좋은 관행입니다.프론트엔드와 백엔드에 동일한 상수가 중복 정의되는 것을 방지하기 위해 공통 상수 파일로 분리하는 것을 고려해보세요:
// shared/constants.ts (새 파일) export const DATETIME_FORMAT: string = 'yyyy-MM-dd HH:mm:ss'; // electron/constants.ts -export const DATETIME_FORMAT: string = 'yyyy-MM-dd HH:mm:ss'; +import { DATETIME_FORMAT } from '../shared/constants'; // src/constants/formats.ts -export const DATETIME_FORMAT: string = 'yyyy-MM-dd HH:mm:ss'; +import { DATETIME_FORMAT } from '../../shared/constants';src/page/TableComposition/hook/useTableFrom.tsx (1)
131-133: 로딩 상태 결합을 단순화하세요.
useEffect를 사용한 로딩 상태 결합은 불필요한 리렌더링을 발생시킬 수 있습니다.다음과 같이 직접 계산하는 방식으로 변경하세요:
- const [isLoading, setIsLoading] = useState(false); - - useEffect(() => { - setIsLoading(postLoading || patchLoading); - }, [postLoading, patchLoading]); + const isLoading = postLoading || patchLoading;Also applies to: 141-141
src/repositories/useAsyncRequest.ts (1)
37-38: 불필요한 타입 단언을 제거하세요.
Promise.race의 결과는 이미 타입 T로 추론되므로 타입 단언이 필요하지 않습니다.- setData(response as T); - return { success: true, data: response as T }; + setData(response); + return { success: true, data: response };src/page/TableListPage/TableListPage.tsx (1)
33-39: 삭제 실패 시 구체적인 에러 메시지를 표시하세요.현재는 일반적인 에러 메시지만 표시되고 있습니다. 사용자에게 더 유용한 정보를 제공할 수 있습니다.
if (!result.success) { - alert('테이블을 삭제하지 못했습니다. 다시 시도해주세요.'); + alert(`테이블을 삭제하지 못했습니다: ${result.error?.message || '알 수 없는 오류가 발생했습니다.'}`); } else {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (24)
electron/api.test.ts(1 hunks)electron/api.ts(3 hunks)electron/constants.ts(2 hunks)electron/main.ts(1 hunks)electron/type.ts(1 hunks)package.json(2 hunks)src/components/async/ErrorIndicator.stories.tsx(1 hunks)src/components/async/ErrorIndicator.tsx(1 hunks)src/components/async/LoadingIndicator.stories.tsx(1 hunks)src/components/async/LoadingIndicator.tsx(1 hunks)src/constants/formats.ts(1 hunks)src/constants/sample_table.ts(3 hunks)src/page/TableComposition/TableComposition.test.tsx(1 hunks)src/page/TableComposition/TableComposition.tsx(4 hunks)src/page/TableComposition/components/TimeBoxStep/TimeBoxStep.tsx(4 hunks)src/page/TableComposition/hook/useTableFrom.tsx(5 hunks)src/page/TableListPage/TableListPage.tsx(3 hunks)src/page/TableOverviewPage/TableOverview.tsx(3 hunks)src/page/TimerPage/TimerPage.tsx(3 hunks)src/page/TimerPage/hooks/useTimerPageState.ts(4 hunks)src/repositories/Result.ts(1 hunks)src/repositories/useAsyncRequest.ts(1 hunks)src/type/type.ts(1 hunks)src/util/type_guard.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (7)
electron/constants.ts (4)
src/constants/formats.ts (1)
DATETIME_FORMAT(1-1)src/constants/sample_table.ts (1)
OPEN_DEBATE_MAIN_ROUND(81-148)electron/type.ts (1)
DebateTableData(34-37)src/type/type.ts (1)
DebateTableData(53-56)
electron/api.ts (1)
electron/constants.ts (1)
DATETIME_FORMAT(3-3)
src/components/async/ErrorIndicator.stories.tsx (1)
src/components/async/ErrorIndicator.tsx (1)
ErrorIndicator(8-27)
src/components/async/LoadingIndicator.stories.tsx (2)
src/components/async/LoadingIndicator.tsx (1)
LoadingIndicator(7-16)src/components/async/ErrorIndicator.stories.tsx (1)
Default(14-18)
src/repositories/useAsyncRequest.ts (1)
src/repositories/Result.ts (1)
Result(11-11)
src/page/TableComposition/hook/useTableFrom.tsx (4)
src/repositories/IPCDebateTableRepository.ts (2)
postTable(17-19)patchTable(27-29)src/repositories/useAsyncRequest.ts (1)
useAsyncRequest(4-70)src/hooks/useBrowserStorage.tsx (1)
useBrowserStorage(12-62)src/type/type.ts (1)
DebateTableData(53-56)
src/page/TimerPage/TimerPage.tsx (4)
src/util/type_guard.ts (1)
isUUID(6-11)src/page/TimerPage/hooks/useTimerPageState.ts (2)
useTimerPageState(30-330)bgColorMap(20-25)src/components/async/LoadingIndicator.tsx (1)
LoadingIndicator(7-16)src/components/async/ErrorIndicator.tsx (1)
ErrorIndicator(8-27)
🔇 Additional comments (30)
package.json (1)
24-24: luxon 의존성 버전 및 보안 검토 결과
- luxon: 최신 버전(3.7.1)
- @types/luxon: 최신 버전(3.6.2)
- 보안 취약점 검사는
package-lock.json(또는yarn.lock)이 필요해 스크립트 환경에서 실행되지 않았습니다.
• 로컬에서 잠금 파일을 생성하세요:• 이후 아래 명령으로 취약점 여부를 확인하시기 바랍니다:npm i --package-lock-onlynpm audit --audit-level=moderatesrc/util/type_guard.ts (2)
3-4: UUID 정규표현식 검증 완료UUID v4 형식의 정규표현식이 정확히 구현되었습니다. 하이픈으로 구분된 8-4-4-4-12 자리 형식과 v4 특성(세 번째 그룹의 첫 번째 문자가 4, 네 번째 그룹의 첫 번째 문자가 8, 9, a, b, A, B 중 하나)을 올바르게 검증합니다.
6-11: 타입 가드 함수 구현 우수TypeScript의 타입 가드 패턴을 적절히 활용하여 런타임 타입 검사와 컴파일 타임 타입 추론을 모두 지원하는 함수가 잘 구현되었습니다.
src/components/async/ErrorIndicator.tsx (1)
3-6: 인터페이스 정의 우수ErrorIndicator 컴포넌트의 props 인터페이스가 명확하게 정의되었습니다. 선택적 props 사용으로 유연성을 제공합니다.
electron/main.ts (1)
7-7: import 경로 리팩토링 승인상수들을 별도의 constants 파일로 분리하는 것은 코드 구조를 개선하는 좋은 리팩토링입니다.
electron/type.ts (1)
19-19: 백엔드-프론트엔드 타입 일관성이 잘 유지되고 있습니다.
datetime필드가src/type/type.ts와 동일하게 추가되어 타입 안전성을 보장하고 있습니다.electron/api.test.ts (1)
15-15: 테스트 데이터가 새로운 인터페이스 구조와 일치하도록 적절히 업데이트되었습니다.
datetime필드를 빈 문자열로 초기화하여 테스트 데이터 구조를 유지하고 있습니다.electron/constants.ts (2)
9-9: 상수 데이터가 새로운 인터페이스 구조와 일치하도록 업데이트되었습니다.
OPEN_DEBATE_MAIN_ROUND상수에datetime필드를 추가하여 타입 일관성을 유지하고 있습니다.
78-78: 상수 데이터가 새로운 인터페이스 구조와 일치하도록 업데이트되었습니다.
OPEN_DEBATE_FINAL_ROUND상수에datetime필드를 추가하여 타입 일관성을 유지하고 있습니다.src/components/async/ErrorIndicator.stories.tsx (1)
1-26: Storybook 설정이 올바르게 구성되었습니다.ErrorIndicator 컴포넌트의 스토리북 스토리가 적절하게 구성되어 있고, 기본 상태와 재시도 버튼이 활성화된 상태 두 가지 케이스를 잘 보여주고 있습니다.
src/components/async/LoadingIndicator.tsx (1)
1-17: 깔끔하고 재사용 가능한 LoadingIndicator 컴포넌트입니다.컴포넌트 구조가 간단하고 명확하며, 적절한 기본 메시지와 함께 일관된 스타일링이 적용되어 있습니다.
electron/api.ts (2)
5-6: DateTime 처리를 위한 적절한 라이브러리 importluxon 라이브러리와 DATETIME_FORMAT 상수를 올바르게 import하여 일관된 날짜 처리가 가능합니다.
56-58: 새 아이템에 대한 적절한 datetime 할당DateTime.local().toFormat()를 사용하여 현재 시간을 일관된 형식으로 할당하는 로직이 올바르게 구현되었습니다.
src/page/TableComposition/components/TimeBoxStep/TimeBoxStep.tsx (3)
18-18: 로딩 상태 처리를 위한 props 추가isLoading prop이 적절히 추가되어 비동기 요청 처리 중 UI 상태를 관리할 수 있습니다.
54-54: 제출 버튼 활성화 로직 개선isLoading 상태를 포함하여 제출 버튼 활성화 조건을 적절히 업데이트했습니다. 로딩 중에 중복 제출을 방지할 수 있습니다.
114-117: 버튼 비활성화 로직 적절히 구현CSS 클래스와 disabled 속성 모두에 isSubmitButtonEnabled 조건을 적용하여 일관된 UI 상태를 유지합니다.
src/components/async/LoadingIndicator.stories.tsx (1)
14-18: 스토리북 설정이 올바르게 구성되어 있습니다.LoadingIndicator 컴포넌트의 스토리북 설정이 표준 패턴을 따르고 있으며, 타입 정의와 메타데이터가 적절합니다.
src/page/TableOverviewPage/TableOverview.tsx (2)
51-55: 조건부 렌더링 로직이 올바르게 구현되어 있습니다.로딩, 에러, 데이터 상태에 따른 조건부 렌더링이 적절하게 구현되어 있고, 재시도 기능도 포함되어 있습니다.
33-35: useEffect의 의존성 배열이 올바르게 설정되어 있습니다.getTable과 id를 의존성 배열에 포함시켜 적절한 리렌더링을 보장하고 있습니다.
src/repositories/Result.ts (1)
1-11: Result 타입 정의가 잘 구성되어 있습니다.discriminated union을 사용한 Result 타입 정의가 적절하며, 성공/실패 상태를 타입 안전하게 처리할 수 있도록 설계되었습니다. 이는 비동기 작업 결과를 처리하는 일반적이고 효과적인 패턴입니다.
src/page/TimerPage/hooks/useTimerPageState.ts (3)
33-38: useAsyncRequest 훅 통합이 올바르게 구현되어 있습니다.새로운 비동기 요청 훅을 적절히 사용하여 로딩, 에러, 데이터 상태를 관리하고 있습니다. 구조 분해 할당을 통해 필요한 상태들을 명확하게 추출하고 있습니다.
139-150: 비동기 데이터 처리 로직이 안전하게 구현되어 있습니다.응답 성공 여부를 확인하고 데이터가 존재할 때만 상태를 업데이트하는 방식이 적절합니다. 에러 처리도 useAsyncRequest 훅에서 자동으로 관리되므로 안전합니다.
326-329: 새로운 상태 값들이 적절히 반환되고 있습니다.error, isLoading, patchedData 상태들이 훅의 반환 객체에 추가되어 컴포넌트에서 비동기 상태를 관리할 수 있도록 구성되어 있습니다.
src/page/TimerPage/TimerPage.tsx (2)
79-96: 조건부 렌더링과 상태 관리가 올바르게 구현되어 있습니다.로딩, 에러, 데이터 상태에 따른 조건부 렌더링이 적절하게 구현되어 있고, patchedData를 사용하여 안전하게 데이터 존재 여부를 확인하고 있습니다.
54-57: 안전한 데이터 접근을 위한 옵셔널 체이닝이 적절히 사용되었습니다.data?.info.name과 같은 옵셔널 체이닝을 통해 안전하게 데이터에 접근하고 있으며, 기본값 처리도 적절합니다.
src/page/TableComposition/TableComposition.tsx (2)
31-36: 비동기 요청 처리가 잘 구현되었습니다!
useAsyncRequest훅을 활용한 데이터 페칭 구현이 깔끔하고, 로딩 상태의 이름을getLoading으로 구분한 것도 좋은 접근입니다.
89-123: 조건부 렌더링이 체계적으로 잘 구성되었습니다!로딩, 에러, 성공 상태에 따른 UI 렌더링이 명확하게 분리되어 있고, 에러 발생 시 재시도 기능도 제공하여 사용자 경험이 향상되었습니다.
src/page/TableComposition/hook/useTableFrom.tsx (1)
96-103: Result 타입 처리가 적절하게 구현되었습니다!성공/실패 케이스를 명확하게 구분하여 처리하고, 성공 시 저장된 폼 데이터를 정리하는 로직이 잘 구성되어 있습니다.
Also applies to: 107-114
src/repositories/useAsyncRequest.ts (1)
4-70: 비동기 요청 훅이 견고하게 구현되었습니다!타임아웃 처리, 에러 핸들링, 상태 관리가 모두 적절하게 구현되어 있습니다. 특히 AbortController를 활용한 타임아웃 구현이 깔끔합니다.
src/page/TableListPage/TableListPage.tsx (1)
15-21: 비동기 상태 관리 리팩토링이 훌륭합니다!
useAsyncRequest를 활용한 데이터 페칭과 삭제 로직이 깔끔하게 구현되었고, 로딩/에러/성공 상태에 따른 조건부 렌더링이 사용자 경험을 크게 향상시킵니다.Also applies to: 57-88
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
정말 많은 작업을 하셨네요 숀 .. 이걸 어떻게 다 하신 것인지 .. 이해하는데도 쉽지 않았는데 숀이 친절하게 PR에 작성해 주셔서 도움이 많이 되었습니다!!!! 질문 위주의 코멘트를 달았으니 편하게 확인해 주셔요!! 수고 많으셨어요 ✨✨👍
| <TestWrapper | ||
| initialEntries={['/composition?mode=edit&tableId=1&mode=CUSTOMIZE']} | ||
| initialEntries={[ | ||
| '/composition?mode=edit&tableId=79800bb7-70a1-4564-b790-e2148967af7e&mode=CUSTOMIZE', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해당 tableId 값은 어디에서 온 건가요?? 임의로 설정해 준 건가용?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 UUID는 src\setup.ts 파일에서 모방 데이터로 오는 2개 샘플 중 1번 샘플의 UUID입니다.
| }} | ||
| /> | ||
| {getLoading && <LoadingIndicator />} | ||
| {!getLoading && error && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
실제로 위의 useEffect에서 throw로 error 던지면 여기서 걸려서 UI가 나오나요 ???
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아뇨. throw로 던져지는 모든 오류는 자동적으로 src\components\ErrorBoundary\ErrorBoundary.tsx로 넘어갑니다. 여기서 잡히는 error는 정확히는 useAsyncRequest의 처리 과정 중 던져진 오류가 바로 던져지지 않고 error로 넘어온 거예요.
| navigate(`/overview/customize/${response.data.info.id}`); | ||
| } else { | ||
| throw new Error('테이블 추가에 실패했어요.'); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네트워크 요청 에러나 그런 것들을 잡을 필요가 없으니까 굳이 try-catch를 사용하지 않은 걸까요 ?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아뇨. 이미 useAsyncRequest에서 예외를 잘 처리하고 있기 때문에 여기서 try-catch-finally를 2중으로 사용할 필요가 없다고 봤습니다.
const onAddTable = async (item: DebateTableData) => {
const response = await postTable(item);
if (response.success) {
await removeValue();
navigate(`/overview/customize/${response.data.info.id}`);
} else {
throw new Error('테이블 추가에 실패했어요.');
}
};내용을 보시면, 2번째 줄에서 response를 패칭하는 과정에서 오류가 잡힐 경우, response.success === false 그리고 response.error === 무언가로 넘어오게 됩니다. 그래서 이후 추가적인 예외 핸들링은 별도로 필요 없을 거라고 생각했어요.
| const result = await deleteTable(tableId); | ||
|
|
||
| if (!result.success) { | ||
| alert('테이블을 삭제하지 못했습니다. 다시 시도해주세요.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
어떤 것은 실패했을 때 throw를 던지고 어떤 것은 alert를 던지는데 어떤 기준으로 다르게 작성하셨는지 궁금해요!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오류를 던진 케이스는 페이지가 테이블 데이터가 없으면 아예 동작하지 못하는 등 시도가 실패했을 때 문제가 매우 큰 경우입니다. 그러나 이 경우는 기본적으로 모든 테이블 목록이 패칭된 상태에서 삭제 동작을 시도하는 것이고, 다시 말해 삭제 동작을 사용자가 실행할 수 있다는 건 전체 테이블 목록이 (일단) 전부 패칭되었음을 의미합니다. 문제가 비교적 사소하다는 말이죠. 따라서 throw를 통해 ErrorBoundary로 넘어가는 게 아니라, 경고 정도로 정리할 수 있게 낮은 수위로 구현했습니다.
| import LoadingIndicator from '../../components/async/LoadingIndicator'; | ||
| import ErrorIndicator from '../../components/async/ErrorIndicator'; | ||
|
|
||
| export default function TableOverview() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
다른 페이지는 TableListPage처럼 Page로 끝나는 이름을 지었는데 이 친구는 폴더는 TableOverviewPage로 되어 있는데 컴포넌트 이름은 TableOverView로 되어 있네요 !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 이건 오랜 전통(?)입니다. 그래도 얘기 나온 김에 정리해둘게요.
|
|
||
| export default function useAsyncRequest<T, Args extends unknown[]>( | ||
| request: (...args: Args) => Promise<T>, | ||
| timeout: number = 5000, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
궁금한 점이 exe 기반의 형태에서도 요청에 오래 걸리는 이유는 무엇일까요 ????
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요청이 오래 걸리진 않습니다. JSON 파일 읽는 거니까 금방 돼요. 근데 개발 중 테스트를 하면서 일부 throw에 잡히지 않는 오류가 무한히 기다리게 만드는 문제가 있더라구요. 그래서 혹시 제가 챙기지 못했을지도 모르는, 식별 불가능한 오류가 발생했을 경우에 대한 최후의 대비책 정도로 생각해주시면 될 것 같습니다.
jaeml06
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
확인했습니다. 새벽까지 작업하시나라 고생많으셨습니다. 몇가지 코멘트 남깁니다. 확인해주시고 작업 계속 진행해주시면 될 것 같습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tanstack query에서 제공하는 훅의 경우, api이외에 실제 비동기 처리 작업을 진행할 때에도 사용가능한데 새롭게 훅을 만들자고 선택한 이유가 있을까요?
있다면
| 또한, 이 훅은 내부적으로 타임아웃 정책을 채택하고 있습니다.
이러한 이유 때문이었는지 궁금합니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TanStack Query 사용해도 되는 거 알고 있습니다만, 다음 이유들로 인해 직접 간단하게 개발하게 되었습니다:
- 말씀하신 대로 타임아웃 정책 적용하려고 한 부분도 있음
- 라이브러리 하나 빼서 용량 줄이기
- 어차피 debate-timer-fe 쪽에서도 비동기 처리를 구현해야 하는데, 그것에 대한 연습 겸 이해 증진을 위해 일부러 직접 개발
🚩 연관 이슈
closed #6
📝 작업 내용
문제 상황
isLoading) 또는 오류(error) 등을 처리하는 로직을 갖고 있지 않았음개선 상황
요약
비동기 요청에서 사용할 수 있는 새 컴포넌트 추가
비동기 요청 중 오류가 발생했거나, 요청을 보낸 후 응답을 기다리고 있을 때 사용할 수 있는 새로운 컴포넌트 2종을 추가했습니다:
비동기 요청을 처리하는 React 훅
useAsyncRequest추가비동기 요청을 처리하는 React 훅
useAsyncRequest을 추가하였습니다. 이 훅의 주된 목적은async키워드가 붙은 비동기 함수의 처리를 간편하고 안전하게 할 수 있도록 돕는 것입니다.이 훅은 기본적으로 TanStack Query의
useQuery함수와 상당히 유사하며, 차이점은 아래 2가지 정도입니다:enabled변수가 없습니다.execute를 직접 실행해야만 가능합니다. 즉, 훅 선언 시 자동으로 요청이 나가는 게 아닙니다.이 훅은 입력으로 다음 값을 받습니다:
async키워드가 붙은 비동기 함수입니다.이 훅은 반환 값으로 다음 유용한 변수 및 함수를 전달합니다:
execute|async키워드가 붙은 요청을 실행합니다.isLoading| 요청 후 불러오는 중일 경우,true를 반환합니다.data| 요청이 성공적이면, 데이터를 반환합니다.error| 요청에 실패할 경우, 오류를 반환합니다.이상의
isLoading,error등을 통해, UI를 요청 진행 상태에 따라 유동적으로 렌더링할 수 있습니다.또한, 이 훅은 내부적으로 타임아웃 정책을 채택하고 있습니다. 지정된 타임아웃 시간 이상 기다릴 경우, 훅은 요청을 중단하고 자동으로 타임아웃 오류를 던집니다. 이 오류 역시 훅의 반환 값 중 하나인
error로 전달되어, 쉽게 핸들링이 가능합니다.기존 UI가 비동기 요청의 상태에 따라 UI를 조건부 렌더링하도록 개선
현재 사용하고 있는 4개 페이지가 개선된 IPC 함수를 적극 활용하여, 데이터 패칭 상태에 따라 다른 UI를 표시하게 개선하였습니다. 이 부분은 코드를 직접 보시는 게 빠를 것 같습니다.
모든 테이블 조회 요청이 시간 순으로 정렬되게 개선
DebateTableData에datetime필드를 추가하였습니다. 또한, 모든 테이블 조회 요청이 시간 순으로 정렬되도록 개선하였습니다. 이를 위해luxon라이브러리를 도입하였음을 알립니다.비고
글자 수 제한 정책은 이미 FE 단에서 자체적으로 막고 있어, 여기서는 적용하지 않습니다.
🏞️ 스크린샷 (선택)
없음
🗣️ 리뷰 요구사항 (선택)
매번 변경 사항이 많네요... 요구 사항은 아니지만, 항상 많은 코드 같이 꼼꼼하게 봐 주셔서, 두 분께 감사하다는 말씀을 남깁니다.
Summary by CodeRabbit
신규 기능
기능 개선
버그 수정
문서 및 테스트
기타