이 방법은 데이터 페칭을 하의 서버 액션에서 처리하고, 이를 페이지 컴포넌트로 전달하는 경우.
//actions.ts
export async function getNutrientAllFunctionalities(params: {
mid: string;
functionalityId: number | null;
}): Promise<
ActionResponse<{
functionalityResponse: z.infer<typeof NutrientFunctionalities.findOneV1.outputRs>;
functionalityMappingsResponse: z.infer<typeof NutrientFunctionalityMappings.findOneV1.outputRs>[];
nutrients: z.infer<typeof NutrientMinimalOutput>[];
existMappingsData: z.infer<typeof NutrientCategoryMappingMinimalOutput>[];
nonMappingData: z.infer<typeof NutrientCategoryMappingMinimalOutput>[];
categoryQuestionsResponse: z.infer<typeof NutrientCategoryQuestions.findAllV1.outputRs>[];
}>
> {
const session = await getSession();
try {
// 기능성 데이터 가져오기
const functionalityResponse = await NutrientFunctionalitiesRepository.findOneV1({
...validatedFields,
pFunctionalityId: params.functionalityId,
});
// 기능성 매핑 데이터 가져오기
const functionalityMappingsResponse = await NutrientFunctionalityMappingsRepository.findOneV1({
...validatedFields,
pFunctionalityId: params.functionalityId,
});
// 하위 성분 데이터 가져오기
const existMappingsData = await NutrientCategoryMappingsRepository.findOneV1({
...validatedFields,
pFunctionalityId: params.functionalityId,
});
// 모든 영양소 데이터 가져오기
const nutrients = await NutrientsRepository.findAllV2({
pInvokerOperatorId: session?.user.operator_id,
pThisOperatorMenuIdentifier: params.mid,
pCallDate: spCallDate(),
});
// 연결되지 않은 영양소 데이터 필터링
const existMappingIds = existMappingsData.map((item) => item.nutrient_id);
const nonMappingData = nutrients.filter((item) => !existMappingIds.includes(item.nutrient_id));
// 문진 질문 데이터 가져오기
const categoryQuestionsResponse = await NutrientCategoryQuestionsRepository.findAllV1({
...validatedFields,
pFunctionalityId: params.functionalityId,
});
return {
status: 'SUCCESS',
message: '모든 데이터를 성공적으로 불러왔습니다.',
data: {
functionalityResponse: functionalityResponse[0],
functionalityMappingsResponse,
nutrients,
existMappingsData,
nonMappingData: nonMappingData.map((item) => ({
...item,
recommend_weight: 0,
recommend_memo: '',
})),
categoryQuestionsResponse,
},
};
} catch (error) {
return errorHandler(error);
}
}
//page.tsx
export default async function Page({ params: { id }, searchParams: { mid } }: PageProps) {
const { status, data } = await getNutrientAllFunctionalities({ mid, functionalityId: Number(id) });
if (status !== 'SUCCESS') {
return <div>데이터를 불러오는 중 오류가 발생했습니다.</div>;
}
return (
<HeaderLayout title="중분류 카테고리 수정" description="중분류 카테고리를 수정할 수 있습니다." backBtn={<BackButton />}>
<div className="flex flex-col gap-2">
<CategoryDetailInfo data={data.functionalityResponse} id={id} />
<TopCategoryView id={Number(id)} mid={mid} data={data.functionalityMappingsResponse} />
<SubCategoryIngredients id={Number(id)} mid={mid} data={data} />
<SubCategoryQuestionTable id={Number(id)} mid={mid} data={data.categoryQuestionsResponse} />
</div>
</HeaderLayout>
);
}
이 방법은 각 컴포넌트가 자신에게 필요한 데이터를 독립적으로 페칭하는 경우.