Thanks to visit codestin.com
Credit goes to github.com

Skip to content

kngsujng/WikiTodo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

98 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WIKITODO(위키투두)

배포 URL : WIKITODO

테스트 계정 ID: [email protected] PW: test1234!


1. 프로젝트 소개

1.1 프로젝트 명 : WIKITODO

  • WIKITODO 서비스는 일정 관리 애플리케이션입니다.
  • 할 일을 등록, 편집, 삭제 및 스크랩, 필터 기능을 제공합니다.
  • 사용자 편의를 위해 다크모드를 지원합니다.
  • 회원 여부에 따라 기능을 차등 지원합니다.

1.2. 개발 환경

[기술 스택]

  • Front-End

  • Back-End




2. 프로젝트 세부 기능

시연 설명
스플래쉬
  • 회원, 비회원 이용 선택
  • 비회원으로 이용하기: 메인 화면으로 이동
  • 로그인하고 이용하기: 로그인 화면으로 이동
로그인
  • '이메일 로그인', '구글계정을 통한 로그인' 선택
  • 이메일 로그인시, 유효성 검사를 진행하고 오류 메시지 제공
  • 이메일과 비밀번호가 유효한 경우 메인 화면으로 이동
  • 구글계정을 통한 로그인시, 계정 선택 후 메인 화면으로 이동
회원가입
  • 이메일 로그인을 위한 회원가입 진행
  • 유효성 검사를 진행하고, 오류 메시지 제공
  • 비밀번호 미리보기 기능 제공

시연 설명
메인 페이지
  • 완료 상태에 따라 필터 기능 제공
  • 할 일 등록, 편집, 삭제 및 스크랩, 완료 토글 기능 제공
  • 다크모드 지원
  • 회원 이용시, 스크랩 모아보기 기능 제공
등록 페이지
  • 카테고리, 제목, 상세 내용, 중요도 표시
  • 모든 필수 항목 입력될 때까지 버튼 비활성화
상세 페이지
  • 메인 페이지에서 할 일을 클릭하면 상세 페이지로 이동
  • 카테고리, 제목, 상세 내용 보여줌
스크랩 페이지
  • 최신 날짜순, 카테고리별, 완료 여부에 따라 스크랩된 할 일 필터링
  • 선택된 카테고리에 해당하는 스크랩된 할 일이 없다면, 문구 표시

3. 프로젝트 주요 기능 설명

☑️ Context API를 통한 전역 상태 관리

사용자 정보와 다크모드 상태를 모든 페이지에서 관리하기 위해 Context API를 사용하였다. 또한, 모든 페이지에서 할 일을 useState를 통해 상태관리하기 보다는, useReducer와 Context API 조합을 이용하여 각 페이지에서 액션만 전달하고 TodoContext에서 모든 상태를 관리하였다.

☑️ React-Query를 활용한 파이어베이스 비동기 데이터 통신과 실시간 UI 업데이트 구현

React-Query를 통해 'scrap'과 'uid'의 조합으로 고유한 key를 생성하고, 이를 활용하여 파이어베이스와의 비동기 데이터 통신을 구현했다. 데이터가 업데이트 되기 전까지 캐시된 정보를 UI에 표시한다. 또한, 스크랩을 선택하거나 해제하면 스크랩된 할 일의 개수가 즉각적으로 업데이트될 수 있도록 하여 사용자에게 신속한 사용자 경험을 제공한다.

☑️ 커스텀 훅을 활용한 로직의 재사용

  1. useInputWithValidation : 로그인과 회원가입 페이지에서 사용되는 이메일과 비밀번호(확인) 유효성 검사 로직 재사용
  2. useTitle: 페이지별 Doc의 title을 제공하여 사용자 경험 향상 (예시 : WikiTodo | 홈, WikiTodo | 등록 등)
  3. useScrap : 사용자의 uid가 존재하는 경우 한해서만 스크랩된 할 일을 즉각적으로 업데이트 하기 위한 React-Query 로직 재사용



4. 트러블 슈팅

4.1. 회원/비회원별 할 일 상태 관리

  • 문제 상황

    • 회원 로그인시, 비회원 데이터가 초기 렌더링되고 난 후 회원 데이터가 렌더링된다.
  • 원인 추론

    • 회원은 파이어베이스를 통해 데이터가 관리되고 있고, 비회원은 로컬스토리지를 통해 데이터를 관리하고 있었기 때문에 파이어베이스에서 비동기 통신을 하는 동안 로컬 스토리지는 브라우저에 저장된 동기적인 데이터기 때문에 초기 렌더링시 즉시 보여준다.
  • 해결 방법

    • 초기 렌더링 시에 로딩 상태를 표시하여 파이어베이스 데이터가 완전히 로드되기 전에 사용자에게 대기 상태를 알렸다.
  • 적용 코드

const TodoProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
	const { user, uid } = useAuthContext();
	const [isLoading, setIsLoading] = useState < boolean > false;
	const [todos, dispatch] = useReducer(todoReducer, []);

	useEffect(() => {
		setIsLoading(true);
		const fetchData = async () => {
			try {
				if (user) {
					const firebaseTodos = await getTodos(uid);
					dispatch({ type: 'SET', todos: firebaseTodos });
				}
				if (!user) {
					const storedTodos = localStorage.getItem('todoList');
					const localTodos: TodoList = storedTodos
						? JSON.parse(storedTodos)
						: [];
					dispatch({ type: 'SET', todos: localTodos });
				}
			} catch (error) {
				console.error('Error fetching todos:', error);
			} finally {
				setIsLoading(false);
			}
		};

		fetchData();
	}, [user, uid]);

	return (
		<TodoContext.Provider value={{ todos, dispatch, isLoading }}>
			{children}
		</TodoContext.Provider>
	);
};

4.2. 임의로 url창 조작하여 페이지 이동 해결

  • 문제 상황

    • 비회원에게 제공되지 않은 scrap페이지를 임의로 url을 조작한 후 페이지 이동 및 이용한다.
  • 원인 추론

    • 회원별 라우터 경로가 차이가 존재하지 않았다.
  • 해결 방법

    • ProtectedRoute 컴포넌트를 생성해서 user가 아닌 사용자가 Scrap 페이지를 이용하려고 하면 main 페이지로 리다이렉트시킨다.
  • 적용 코드

...
<Route
	path="/scrap"
	element={
		<ProtectedRoute>
			<Scrap />
		</ProtectedRoute>
}
/>
...
const ProtectedRoute = ({ children }: { children: ReactNode }) => {
	const { user } = useAuthContext();
	if (!user) {
		return (
			<Navigate
				to="/main"
				replace
			/>
		);
	}
	return children;
};
export default ProtectedRoute;

About

React 18, React-Query, TypeScript 등을 공부하기 위해 제작한 Web App

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published