[SideProject] - 개인 프로젝트 - TeddyLog 03. 습관 가져오기
in Programming on Sideproject, React, Next, Firestore
이제는 Habit을 생성하고 수정하는 기능을 만들어보자.
기본적인 투두리스트와 다른점은
생성을 할 경우 firestore 서버에 저장되며 GoalHabits에 저장되고 수정되며
실제 Habit의 카운팅 및 기록은 HabitsLog에 저장된다.
다음날이 되면 GoalHabits를 기준으로 새로운 HabitsLog를 count 0 으로 자동생성한다.
해야할 것
- 목표 습관 생성 (Fab 버튼으로 생성)
- 습관 기록 오늘 습관에서도 추가
- 목표 습관 삭제 (롱프래스로 삭제)
- 습관 기록 오늘 습관에서도 삭제
- 습관 기록 조회하여 현재 날짜 기준 있는지 확인 (첫 화면 시작하면 불러올 데이터)
- 없으면 목표 습관 내용으로 오늘 신규 습관 생성
- 있으면 습관 목록 반환
- 습관 count update
로직 Flow
1. 습관 목록 가져오기
2. 습관 생성
3. 습관 count update
4. 습관 삭제
이제 해당 Flow를 개발을 진행해보자
초기 설정
habitSlice.ts 를 만들어주자.
export interface IHabit {
name: string;
goalCount: number;
currentCount: number | undefined;
}
export interface HabitState {
habits: IHabit[];
}
const initialState: HabitState = {
habits: [],
};
export const habitSlice = createSlice({
name: 'habit',
initialState,
reducers: {},
extraReducers: (builder) => {
}
})
그리고 configureStore에 등록해주자.
export const store = configureStore({
reducer: {
auth: authSlice.reducer,
user: userSlice.reducer,
habit: habitSlice.reducer,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware(),
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
이제 기능을 구현하면 된다!
1. 습관 목록 가져오기
먼저 습관 목록을 가져오는 기능을 만들어보자.
기능에서 해야하는 순서로는
- Date()를 활용해 오늘 날짜 추출
- Users/{uid}/HabitsLog/{date} 로 doc 가져오기
- doc이 있으면
- Users/{uid}/HabitsLog{date}/Habits 의 doc을 반환하기
- doc이 없으면
- Users/{uid}/HabitsLog/{date} 에 초기값으로 doc 생성하기
- Users/{uid}/GoalHabit 에서 docs가져오기
- 해당 docs로 Users/{uid}HabitsLog/{date}/Habits 에 목록 만들기
- 해당 docs 반환하기
뼈대를 만들어보자
createAsyncThunks를 활용해서 함수를 생성한다.
export const fetchHabitsRequest = createAsyncThunk(
'habit/fetchHabitsRequest',
async ({ uid }: IFetchHabitsRequest, { rejectWithValue }) => {
try {
} catch (e) {
console.error(e);
}
}
);
해당 정보를 가져올때 필요한 uid 정보만 받도록 하였다.
date 생성
const now = new Date(); const date = `${now.getFullYear()}-${now.getMonth()}-${now.getDay()}`;console.log(date);
Users/{uid}/HabitsLog/{date} 로 doc 가져오기
const habitLogRef = doc(db, 'Users', uid, 'HabitsLog', date); const docSnapshot = await getDoc(habitLogRef); if(docSnapshot.exists()) { ... } else { ... }
doc이 존재하면? Users/{uid}/HabitsLog/{date}/Habits 의 doc을 반환하기
const habitsCollection = collection( db, 'Users', uid, 'HabitsLog', date, 'Habits' ); const habits = await getDocs(habitsCollection); return habits.docs.map((e) => ({ id: e.id, habitRef: e.data().habitRef, name: e.data().name, goalCount: e.data().goalCount, currentCount: e.data().currentCount, }));
doc이 없으면? Users/{uid}/HabitsLog/{date} 에 초기값으로 doc 생성하기
await setDoc(habitLogRef, { date, success: false, });
doc이 없으면? Users/{uid}/GoalHabit 에서 docs가져오기
const todayHabitLogCollection = collection( db, 'Users', uid, 'HabitsLog', date, 'Habits' ); const goalHabitCollection = collection(db, 'Users', uid, 'GoalHabits'); const goalHabits = await getDocs(goalHabitCollection);
해당 docs로 Users/{uid}HabitsLog/{date}/Habits 에 목록 만들기
const result = []; for (const goalhabit of goalHabits.docs) { const { name, goalCount } = goalhabit.data(); const ref = await addDoc(todayHabitLogCollection, { name, goalCount, currentCount: 0, habitRef: goalhabit.ref, }); result.push({ id: ref.id, name, goalCount, currentCount: 0, habitRef: goalhabit.ref, }); } return result;
마지막으로 reducer에 연결해주자.
export const habitSlice = createSlice({
name: 'habit',
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchHabitsRequest.fulfilled, (state, action) => {
state.habitFetchError = null;
state.habitFetchLoading = 'succeeded';
state.habits = action.payload ?? [];
})
.addCase(fetchHabitsRequest.rejected, (state, action) => {
state.habitFetchError = action.payload as string;
state.habitFetchLoading = 'failed';
})
.addCase(fetchHabitsRequest.pending, (state, action) => {
state.habitFetchLoading = 'pending';
state.habitFetchError = null;
});
},
});
해당 내용을 firestore에 dummy데이터를 넣어놓고 테스트해보자.
위와 같이 목표 습관을 만들어 놓고 실행해보았다.
아주 잘 생성된다.
화면 또한 아주 잘 보인다!
다음에는 목표 습관 생성을 개발해보자.