, 'fallback'> {
diff --git a/frontend/src/components/@common/Loading/Loading.tsx b/frontend/src/components/@common/Loading/Loading.tsx
new file mode 100644
index 000000000..bf677a852
--- /dev/null
+++ b/frontend/src/components/@common/Loading/Loading.tsx
@@ -0,0 +1,9 @@
+import { PropsWithChildren, Suspense } from 'react';
+
+import LoadingSpinner from '../LoadingSpinner/LoadingSpinner';
+
+const Loading = ({ children }: PropsWithChildren) => (
+ }>{children}
+);
+
+export default Loading;
diff --git a/frontend/src/components/@common/LoadingSpinner.tsx b/frontend/src/components/@common/LoadingSpinner/LoadingSpinner.tsx
similarity index 100%
rename from frontend/src/components/@common/LoadingSpinner.tsx
rename to frontend/src/components/@common/LoadingSpinner/LoadingSpinner.tsx
diff --git a/frontend/src/components/Food/FilterBottomSheet/FilterBottomSheet.tsx b/frontend/src/components/Food/FilterBottomSheet/FilterBottomSheet.tsx
index 7dbecddec..a4b6be56a 100644
--- a/frontend/src/components/Food/FilterBottomSheet/FilterBottomSheet.tsx
+++ b/frontend/src/components/Food/FilterBottomSheet/FilterBottomSheet.tsx
@@ -3,7 +3,7 @@ import styled, { css } from 'styled-components';
import SettingsIcon from '@/assets/svg/settings_outline_icon.svg';
import { Dialog } from '@/components/@common/Dialog/Dialog';
-import QueryBoundary from '@/components/@common/ErrorBoundary/QueryBoundary/QueryBoundary';
+import Loading from '@/components/@common/Loading/Loading';
import Tabs from '@/components/@common/Tabs/Tabs';
import { FoodFilterProvider, useFoodFilterContext } from '@/context/food';
import { useFoodListFilterMetaQuery } from '@/hooks/query/food';
@@ -20,25 +20,22 @@ import NutritionStandardsFilterList from './NutritionStandardsFilterList/Nutriti
const FilterBottomSheet = () => (
-
-
-
-
+
);
diff --git a/frontend/src/components/PetProfile/PetListBottomSheet.tsx b/frontend/src/components/PetProfile/PetListBottomSheet.tsx
index 500dddc74..4f89dcdaa 100644
--- a/frontend/src/components/PetProfile/PetListBottomSheet.tsx
+++ b/frontend/src/components/PetProfile/PetListBottomSheet.tsx
@@ -1,20 +1,20 @@
import { styled } from 'styled-components';
import { Dialog } from '../@common/Dialog/Dialog';
-import QueryBoundary from '../@common/ErrorBoundary/QueryBoundary/QueryBoundary';
import UserProfile from '../@common/Header/UserProfile';
+import Loading from '../@common/Loading/Loading';
import PetList from './PetList';
const PetListBottomSheet = () => (
);
diff --git a/frontend/src/components/Review/ReviewList/SummaryChart/SummaryChart.tsx b/frontend/src/components/Review/ReviewList/SummaryChart/SummaryChart.tsx
index acc5e5dfd..dc49a2a81 100644
--- a/frontend/src/components/Review/ReviewList/SummaryChart/SummaryChart.tsx
+++ b/frontend/src/components/Review/ReviewList/SummaryChart/SummaryChart.tsx
@@ -1,7 +1,6 @@
-import { PropsWithChildren } from 'react';
+import { PropsWithChildren, Suspense } from 'react';
import styled, { css } from 'styled-components';
-import QueryBoundary from '@/components/@common/ErrorBoundary/QueryBoundary/QueryBoundary';
import StarRatingDisplay from '@/components/@common/StarRating/StarRatingDisplay/StartRatingDisplay';
import Tabs from '@/components/@common/Tabs/Tabs';
import { REVIEW_SUMMARY_KEYWORDS } from '@/constants/review';
@@ -31,9 +30,9 @@ const SummaryChart = () => {
{summaryKeywords.map(keyword => (
- }>
+ }>
-
+
))}
diff --git a/frontend/src/types/common/utility.ts b/frontend/src/types/common/utility.ts
index d51b0e037..6cc26457e 100644
--- a/frontend/src/types/common/utility.ts
+++ b/frontend/src/types/common/utility.ts
@@ -1,14 +1,16 @@
import { ReactNode } from 'react';
-export type RenderProps = (payload: P) => ReactNode;
+type RenderProps
= (payload: P) => ReactNode;
-export type Unpack = T extends (infer U)[] ? U : T extends Set ? U : T;
+type Unpack = T extends (infer U)[] ? U : T extends Set ? U : T;
-export type Parameter unknown> = Parameters[0];
+type Parameter unknown> = Parameters[0];
-export type StyledProps = { [K in keyof T as `$${string & K}`]: T[K] };
+type StyledProps = { [K in keyof T as `$${string & K}`]: T[K] };
-export type Values = T[keyof T];
+type Values = T[keyof T];
+
+type BaseFunction = (...args: never[]) => unknown;
type Separator = '_';
@@ -24,7 +26,9 @@ type Replace = IsCapitalized extends true
? `${Separator}${Lowercase}`
: Char;
-export type CamelToSnake<
+type CamelToSnake<
Str extends string,
Acc extends string = '',
> = Str extends `${infer Char}${infer Rest}` ? CamelToSnake}`> : Acc;
+
+export type { BaseFunction, CamelToSnake, Parameter, RenderProps, StyledProps, Unpack, Values };
diff --git a/frontend/src/utils/compound.ts b/frontend/src/utils/compound.ts
index 6dc538f68..18b3be51a 100644
--- a/frontend/src/utils/compound.ts
+++ b/frontend/src/utils/compound.ts
@@ -1,6 +1,6 @@
import { Children, isValidElement, PropsWithChildren, ReactElement, ReactNode } from 'react';
-import { RenderProps } from '@/types/common/utility';
+import type { BaseFunction, RenderProps } from '@/types/common/utility';
export type AsChild = {
asChild?: boolean;
@@ -54,4 +54,10 @@ export const getValidProps = (
export const resolveRenderProps =
(
renderProps: ReactNode | RenderProps
,
payload: P,
-) => (typeof renderProps === 'function' ? renderProps(payload) : renderProps);
+) => resolveFunctionOrPrimitive(renderProps, payload);
+
+export const resolveFunctionOrPrimitive = (
+ functionOrPrimitive: T,
+ ...payload: T extends BaseFunction ? Parameters : never[]
+): T extends BaseFunction ? ReturnType : T =>
+ typeof functionOrPrimitive === 'function' ? functionOrPrimitive(...payload) : functionOrPrimitive;
diff --git a/frontend/src/utils/errors.ts b/frontend/src/utils/errors.ts
index a706f077a..b4686b74d 100644
--- a/frontend/src/utils/errors.ts
+++ b/frontend/src/utils/errors.ts
@@ -40,7 +40,7 @@ class ZipgoError extends Error {
this.cause = options.cause;
- this.ignore = false;
+ this[IGNORE_KEY] = false;
}
static convertToError(error: unknown) {
@@ -56,9 +56,9 @@ class ZipgoError extends Error {
class RuntimeError extends ZipgoError {
constructor(info: ErrorInfo, value?: unknown) {
- super(info, JSON.stringify(value));
+ super(info, value);
- this.ignore = true;
+ this[IGNORE_KEY] = true;
}
}
@@ -66,12 +66,12 @@ class UnexpectedError extends ZipgoError<'UNEXPECTED_ERROR'> {
constructor(value?: unknown) {
super({ code: 'UNEXPECTED_ERROR' }, value);
- this.ignore = true;
+ this[IGNORE_KEY] = true;
}
}
class APIError extends ZipgoError {
- status;
+ status: number;
constructor(error: ManageableAxiosError, D>>) {
/** @description 서버의 코드 미제공 방지 */
@@ -80,6 +80,8 @@ class APIError extends ZipgoError {
super({ code });
this.status = error.response.status;
+
+ this[IGNORE_KEY] = error.config.method !== 'get';
}
/**
@@ -101,10 +103,10 @@ const createErrorParams = (
return [message, options];
};
-const shouldIgnore = (error: Error, ignoreKey = IGNORE_KEY) =>
+const isIgnored = (error: E, ignoreKey = IGNORE_KEY) =>
Object.prototype.hasOwnProperty.call(error, ignoreKey) &&
- (error as Error & { [key in typeof ignoreKey]: boolean })[ignoreKey];
+ (error as E & { [key in typeof ignoreKey]: boolean })[ignoreKey];
-export { APIError, RuntimeError, shouldIgnore, UnexpectedError, ZipgoError };
+export { APIError, isIgnored, RuntimeError, UnexpectedError, ZipgoError };
export type { ManageableAxiosError };