코드 출처 : https://github.com/Cluster-Taek/next14-boilerplate
GitHub - Cluster-Taek/next14-boilerplate
Contribute to Cluster-Taek/next14-boilerplate development by creating an account on GitHub.
github.com
users/page.tsx
'use client';
import Button from '@/components/common/button';
import UserCreateFormModal from '@/components/user/user-create-form-modal';
import { MODAL } from '@/constants/modal-key-constants';
import useModals from '@/hooks/use-modals';
import { useUsers } from '@/lib/user';
import { sva } from '@/styled-system/css';
import { Box } from '@/styled-system/jsx';
const Page = () => {
const pageStyle = PageSva();
const { openModal } = useModals();
const { data: users } = useUsers({
_page: 1,
_per_page: 10,
});
const handleClickCreateButton = () => {
openModal({
id: MODAL.USER_CREATE,
component: <UserCreateFormModal />,
});
};
return (
<Box className={pageStyle.wrapper}>
<Box className={pageStyle.list}>{users?.data?.map((user) => <Box key={user.id}>{user.name}</Box>)}</Box>
<Button onClick={handleClickCreateButton}>Create</Button>
</Box>
);
};
export default Page;
const PageSva = sva({
slots: ['wrapper', 'list', 'form', 'input', 'error'],
base: {
wrapper: {
display: 'flex',
width: 'full',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
height: 'full',
},
list: {
width: 'full',
display: 'flex',
flexWrap: 'wrap',
gap: '4',
},
form: {
width: 'full',
marginTop: '4',
},
input: {
width: 'full',
padding: '2',
marginTop: '2',
},
error: {
color: 'red',
marginTop: '2',
},
},
});
사용자 목록을 표시하고 새로운 사용자를 추가하기 위한 모달을 열 수 있는 React 클라이언트 구성 요소입니다.
모듈 구성
이 코드의 주요 목적은 사용자 목록을 렌더링하고 새 사용자 추가를 위한 모달을 열 수 있는 기능을 제공합니다.
주요 흐름
- useUsers 훅을 통해 데이터를 가져옵니다.
- openModal 훅을 사용해 모달을 엽니다.
- PageSva로 스타일링을 관리하며, Box 컴포넌트를 통해 레이아웃을 구성합니다.
'use client'
이 문구는 Next.js에서 사용되며, 이 파일이 클라이언트에서 렌더링되는 React 컴포넌트임을 나타냅니다.
즉, 서버에서 실행되지 않고 브라우저에서 실행됩니다.
import 문
여러 컴포넌트, 훅, 스타일링 함수 등을 가져옵니다:
- Button: 공통 버튼 컴포넌트.
- UserCreateFormModal: 사용자를 생성하는 폼을 포함한 모달 컴포넌트.
- MODAL: 모달 키를 상수로 정의한 파일.
- useModals: 모달을 열고 닫는 커스텀 훅.
- useUsers: 사용자 데이터를 가져오는 커스텀 훅.
- sva와 Box: 스타일링 및 레이아웃 구성을 위한 함수 및 컴포넌트.
Page 컴포넌트
주요 구성 요소:
- pageStyle
- PageSva를 호출하여 스타일 객체를 생성합니다.
- 이 객체는 페이지에 필요한 스타일링 정보를 담고 있습니다.
- useUsers
- _page와 _per_page를 쿼리 파라미터로 사용하여 사용자 데이터를 가져옵니다.
- users?.data는 사용자 데이터를 배열로 반환합니다.
- handleClickCreateButton
- 모달을 열기 위한 함수입니다.
- openModal 함수에 id와 component를 전달하여 특정 모달을 엽니다.
- JSX 반환
- Box 컴포넌트를 사용하여 스타일링된 페이지 레이아웃을 렌더링합니다.
- users?.data를 반복하여 사용자 이름을 리스트로 표시합니다.
- Button 컴포넌트를 사용하여 "Create" 버튼을 렌더링하고, 클릭 시 handleClickCreateButton을 호출합니다.
PageSva 함수
- slots 스타일 슬롯 이름 배열. 각 슬롯은 CSS 스타일 객체를 나타냅니다.
- base 각 슬롯에 대한 기본 스타일 정의:
- wrapper: 페이지의 최상위 컨테이너 스타일. 중앙 정렬과 전체 화면 높이를 사용합니다.
- list: 사용자 리스트를 래핑하는 컨테이너. 가로와 세로 모두 유연하게 배치되며, 요소 간의 간격(gap)이 정의됩니다.
- form, input, error: 사용자 입력 폼 및 오류 메시지와 관련된 스타일.
user.ts
import { fetchApi } from './base';
import { IPageable } from '@/types/pageable';
import { IUser } from '@/types/user';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
export interface IUsersParams {
// paging params of json-server
_page: number;
_per_page: number;
}
export const useUsers = (params: IUsersParams) => {
return useQuery<IPageable<IUser>>({
queryKey: [`/api/users`, params],
});
};
useUsers 훅은 React Query를 사용하여 사용자 데이터를 가져오는 커스텀 훅입니다.
useUsers는 특정한 파라미터를 기반으로 사용자 데이터를 서버에서 가져오고, 이를 React 컴포넌트에서 쉽게 사용할 수 있도록 데이터 상태를 관리합니다.
- useQuery: React Query에서 제공하는 함수로, 데이터를 가져오는 요청을 관리하며 로딩 상태, 오류, 캐싱 등을 처리합니다.
- IPageable<IUser>: 사용자 데이터의 페이징 정보를 포함하는 타입 정의입니다.
(params: IUsersParams)
- params: JSON Server에서 페이징 요청을 처리하기 위한 파라미터 객체입니다.
- _page: 가져올 페이지 번호.
- _per_page: 페이지당 항목 수.
useQuery를 호출한 결과를 반환하며, 다음 상태와 데이터를 제공합니다:
- data: 서버에서 가져온 사용자 데이터.
- isLoading: 데이터가 로딩 중인지 나타내는 불리언 값.
- isError: 요청이 실패했는지 나타내는 불리언 값.
- refetch: 데이터를 다시 가져오는 함수.
내부 동작
return useQuery<IPageable<IUser>>({
queryKey: [`/api/users`, params],
});
- queryKey: 캐싱 및 데이터를 식별하기 위한 고유 키입니다.
- URL과 파라미터(params)를 조합해 지정합니다.
- 동일한 키를 사용하면 캐싱된 데이터를 재사용합니다.
- IPageable<IUser>: 데이터의 타입을 명시적으로 지정해 TypeScript가 반환 데이터를 올바르게 추론할 수 있도록 합니다.
useUsers의 사용 부분 from users/page.tsx
const { data: users } = useUsers({
_page: 1,
_per_page: 10,
});
- _page: 1: 첫 번째 페이지 데이터를 요청합니다.
- _per_page: 10: 한 페이지당 10명의 사용자를 요청합니다.
결과
useUsers 훅은 React Query의 useQuery를 활용하여 사용자 데이터를 가져오고, 이를 data라는 이름으로 반환합니다.
- 반환된 data를 users라는 이름으로 구조 분해 할당하였습니다.
데이터를 사용하는 부분
users 데이터는 아래와 같이 JSX에서 사용됩니다
<Box className={pageStyle.list}>
{users?.data?.map((user) => (
<Box key={user.id}>{user.name}</Box>
))}
</Box>
- users?.data
- users 객체의 data 속성은 사용자 목록 배열입니다.
- 이 배열은 IPageable<IUser> 타입으로 정의되었으며, 각 요소는 IUser 타입(사용자 정보 객체)입니다.
- map을 이용한 반복 렌더링
- users?.data 배열을 순회하며 각 사용자 데이터를 TSX로 렌더링합니다.
- user.id는 각 사용자 객체의 고유 ID이며, React에서 리스트를 렌더링할 때 key로 사용됩니다.
- user.name은 사용자 이름을 표시합니다.
- 안전한 옵셔널 체이닝
- 데이터가 아직 로딩되지 않았거나 users가 null인 경우를 대비해 users?.data로 접근합니다.
- 이로 인해 런타임 에러를 방지합니다.
사용 흐름
- 데이터 요청: useUsers 훅을 호출하여 1페이지의 10명의 사용자 데이터를 요청합니다.
- 데이터 수신 및 캐싱: React Query가 데이터를 서버에서 가져와 캐싱합니다.
- 사용자 이름 렌더링: users?.data 배열을 순회하며 사용자 이름을 화면에 표시합니다.
'개발 공부 > React' 카테고리의 다른 글
| Next.js 에서 모달 띄우기와 서버작업을 통한 유저 정보 받기 및 등록 (3) (1) | 2025.01.04 |
|---|---|
| Next.js 에서 모달 띄우기와 서버작업을 통한 유저 정보 받기 및 등록 (2) (0) | 2025.01.03 |
| Next.js에서 레이아웃 구성 (3) / ModalProvider (1) | 2024.12.29 |
| Next.js에서 레이아웃 구성 (2) / QueryProvider (0) | 2024.12.26 |
| Next.js에서 레이아웃 구성 (1) / SessionProvider, AuthProvider (1) | 2024.12.25 |