-
Notifications
You must be signed in to change notification settings - Fork 5
대시보드 Jotai 상태 관리
대시보드는 Trello와 같은 Kanban 스타일 보드에서 다양한 카드와 컬럼을 생성, 편집, 삭제할 수 있는 기능을 제공합니다. Jotai는 간단한 원자(atoms)를 사용하여 상태를 추적하고 이 상태를 바탕으로 컴포넌트의 상태를 업데이트합니다. 이 상태 관리 방법을 중심으로 코드를 설명하겠습니다.
Jotai에서 Atom은 컴포넌트가 사용할 수 있는 상태의 가장 작은 단위입니다. 이 코드는 여러 가지 Atom을 정의하여 각각의 상태를 관리하고 있습니다.
-
dashboardCardUpdateAtom
: 카드가 업데이트되는지 여부를 나타내는 boolean 상태. -
currentDashboardIdAtom
: 현재 대시보드의 ID를 추적하기 위한 상태. -
currentColumnListAtom
: 현재 대시보드에 있는 모든 컬럼의 리스트 상태. -
resetColumnListAtom
: 특정 대시보드 ID로 현재 컬럼 리스트를 초기화하는 데 사용되는 atom입니다. 특정 대시보드를 선택하면 이 atom을 통해 해당 대시보드의 컬럼 리스트를 초기화합니다. -
columnCardsAtom
: 각 컬럼의 카드 상태를 관리하는 객체로, 컬럼별 카드 리스트 및 추가 카드 로딩 여부, 카드의 전체 수 등을 추적합니다.
export interface ColumnCards {
[columnId: number]: {
cards: ICard["cards"];
hasMore: boolean; // 추가 로딩할 카드가 더 있는지 여부
cursorId: number | null; // 카드의 마지막 아이디를 통해 다음 카드 로딩을 결정
totalCount: number; // 카드의 전체 개수
};
}
export const columnCardsAtom = atom<ColumnCards>({});
- **
initiModalState
**와ModalStateAtom
: 모달들의 상태를 한 곳에서 관리합니다. 예를 들어 카드 생성 모달, 카드 수정 모달, 컬럼 생성 모달 등이 있는데, 각 모달의 열림 여부를 boolean 값으로 추적합니다.
export const initiModalState = {
createDashboard: false, // 대시보드 생성 모달
createCard: false, // 할 일 카드 생성 모달
detailCard: false, // 할 일 카드 상세 모달
updateCard: false, // 할 일 카드 수정 모달
createColumn: false, // 컬럼 생성 모달
editColumn: false, // 컬럼 수정 모달
invitationDashboard: false, // 대시 보드 초대 모달
deleteModal: false, // 알람 모달
};
export const ModalStateAtom = atom(initiModalState);
이러한 atom들은 대시보드 애플리케이션에서 모달의 열림 여부를 관리하는 데 사용됩니다.
-
DeleteModalStateAtom
: 삭제 모달에서 어떤 제목을 보여줄지와 삭제를 확인했을 때 실행될 콜백 함수를 저장하는 데 사용됩니다.
-
ColumnAtom
: 특정 컬럼의 ID와 제목을 추적하기 위한 상태. -
CardIdAtom
: 상세 카드 모달을 열 때 특정 카드의 ID를 추적하는 상태.
DashboardDetail
컴포넌트는 대시보드의 상세 내용을 보여주며, 여기서 컬럼 및 카드들을 렌더링합니다. 이 컴포넌트에서 Jotai를 사용하여 상태를 관리하고 있습니다.
-
컬럼 초기화 및 설정: 대시보드를 선택할 때 **
setResetColumnList
**로 컬럼 리스트를 초기화합니다.useEffect(() => { if (dashboardId) { setResetColumnList(dashboardId); } }, [dashboardId, setResetColumnList]);
-
컬럼 데이터 가져오기:
getColumn
함수는 선택한 대시보드의 컬럼을 가져와 **setCurrentColumnList
**에 설정합니다. 이를 통해 렌더링할 컬럼 리스트를 업데이트합니다.setCurrentColumnList( columns.map((column: IColumnData) => ({ id: column.id, title: column.title, })) );
-
카드 업데이트 시 실시간 반영:
isCardUpdate
상태가true
일 때 **getColumn
**을 호출하여 카드 리스트를 다시 가져오고, 이후 **isCardUpdate
**를false
로 설정합니다.useEffect(() => { if (isCardUpdate) { getColumn(); setIsCardUpdate(false); } }, [getColumn, isCardUpdate, setIsCardUpdate]);
-
드래그 앤 드롭 처리:
onDragEnd
함수는 드래그 앤 드롭 라이브러리를 사용하여 카드가 드래그되어 이동되었을 때의 로직을 처리합니다. 여기서 카드의 위치를 변경하고, 해당 상태를 Jotai의 **columnCardsAtom
**과 **columnList
**에 반영합니다.setColumnCards(updatedColumnCards); setColumnList(updatedColumnList);
ColumnList
컴포넌트는 각 컬럼과 그 안의 카드들을 보여줍니다. 여기서 무한 스크롤을 사용해 카드를 더 로딩하고, 컬럼의 수정 및 카드의 세부 내용을 확인하는 기능을 제공합니다.
-
카드 추가 로드:
loadMoreCards
함수는 특정 컬럼의 카드가 더 필요할 때 호출되어 새로운 카드를 불러옵니다. 상태를 업데이트하면서 현재 로딩 여부를isLoading
상태로 관리합니다.const loadMoreCards = useCallback(async () => { if (!currentColumn.hasMore || isLoading || !currentColumn.cursorId) return; setIsLoading(true); // API 요청을 통해 새로운 카드 가져오기 // ... setIsLoading(false); }, [columnId, currentColumn.hasMore, currentColumn.cursorId, isLoading, setColumnCards]);
-
Intersection Observer: **
useEffect
**를 사용하여 Intersection Observer를 설정하고, 컬럼의 마지막 요소가 화면에 보일 때마다 새로운 카드를 불러옵니다.useEffect(() => { const observer = new IntersectionObserver( (entries) => { if (entries[0].isIntersecting && currentColumn.hasMore && !isLoading) { loadMoreCards(); } }, { root: null, rootMargin: "50px", threshold: 0.1 } ); // observer 설정 및 정리 로직 // ... }, [currentColumn.hasMore, isLoading, loadMoreCards]);
대시보드는 Jotai를 사용하여 대시보드의 상태와 모달 상태, 컬럼 및 카드 상태를 관리합니다. 주요 상태들은 Atom으로 정의되어 있고, 이를 컴포넌트에서 사용하여 대시보드의 변경 사항을 반영합니다.
- Atom을 사용한 상태 분리: 상태를 각각의 작은 단위로 분리하여 각 컴포넌트가 필요한 상태만 가져다 쓰게 합니다.
-
useAtom
과useSetAtom
을 이용한 상태 변경: 컴포넌트에서 특정 상태를 읽거나 설정할 때 Jotai 훅을 사용합니다. -
콜백 함수와
useEffect
를 통한 비동기 데이터 로딩: 상태를 비동기적으로 업데이트하며, Intersection Observer를 사용해 필요한 경우에만 데이터를 불러옵니다.