새로운 기능 구현, 그리고 열심히 삽질한 결과

bamzzi15·6일 전
0

배포 성공하고 신나서 글을 쓴다.


📢 아-아-
📢 업데이트된 기능을 말씀드리겠습니다

  1. 파이어베이스 이용해 구글 계정으로 로그인/로그아웃
  2. 로딩 페이지
  3. 사용자별 식단표 등록 가능(서버에 저장하고, 불러오기가 됩니다!)
  4. 반찬 여러개 등록 가능
  5. 파이어베이스로... 배포! 🏆


파이어베이스 이용해 구글 계정으로 로그인/로그아웃

파이어베이스에서 제공해주는 signInWithPopup, GoogleAuthProvider, onAuthStateChanged 를 이용해 구글 계정으로 로그인 기능을 구현했다.

로그인 구현 중 느꼈던 어려움

따로 글을 작성하긴 했지만... 다시 한 번!

로그인 한 사용자의 정보를 가져올 때에는 onAuthStateChanged 를 이용했다. 공식문서
로그인한 사용자의 정보를 이용해 서버에 등록되어있는 식단표를 가져오는 방식으로 진행하고 있었다.
그런데, 로그인이 된 후 식단표 템플릿이 먼저 렌더링되고, 잠깐 딜레이가 있다가 식단표가 나타나는 현상이 있었다.

구분을 쉽게 하기위해 느리게 효과를 줬다.



로딩 페이지

gif에는 굉장히 오랜시간동안 빈 달력이 보여지는 것 같지만, 사실 더 짧은 간격으로 렌더링이 되고 있었다.
이대로 두기엔 좋지 않은 사용자 경험이 될 것 같아 식단표를 불러오기까지의 시간 동안 로딩페이지가 보여지게끔 구현했다.

const [isLoading, setIsLoading] = useState(false);
  async function setMealTable() {
    
	// 식단표 렌더링하는 함수
    
  }

  useEffect(() => {
    (async () => {
      setIsLoading(true); // 로딩 true
      checkUserAuthentication(); // 유저 체크
      await setMealTable(); // 식단표가 렌더링 되면
      setIsLoading(false); // 로딩 false
    })();
  }, []);

// state를 이용해 보여지는 컴포넌트가 다름
return isLoading ? (
    <Loading />
  ) : (
    <div>
      <Navbar />
      <S.MealTableWapper>
        <Calendar />
        <MenuLayout />
      </S.MealTableWapper>
    </div>
  );
}

이 코드를 작성하면서도... 저 useEffect 내 함수를 잘 작성한 것이 맞는가? 에 대한 의문이 너무 크다. async-await 개념을 다시 공부해야겠다....

그래서 구현한 결과!

따로 빈 달력이 렌더링 되는 일 없이 바로 식단표가 보여지게끔 잘 구현됐다!




사용자별 식단표 등록 가능(서버에 저장하고, 불러오기가 됩니다!)

로그인이 구현됐기 때문에 사용자별로 식단표가 저장될 수 있게 됐다!
로그인을 하면 유저 고유 id가 부여되는데, 그 id를 활용해 서버에 식단표가 저장될 때 객체를 유저고유 id (key)와 유저의 식단표(value)로 저장되게끔 했다.

그래서 불러올 때도 유저 고유 id로 해당되는 키가 있을 때 식단표를 불러올 수 있게끔 했다.

서버에 저장할 때는 파이어베이스의 setDoc을, 서버에 저장되어 있는 데이터를 불러올 때는 getDoc을 사용했다.


// 식단표 저장 함수

export async function setUserMenuList(menuList: MenuType[], userId: string) {
  try {
    await setDoc(doc(firestore, "users", userId), { menuList });
    alert("저장되었습니다.");
  } catch (e) {
    console.log("등록 중 에러가 발생했습니다.", e);
  }
}



반찬 여러개 등록 가능

드디어 반찬을 여러개 등록할 수 있게 됐다. 😋

적용 전, 1개만 등록 가능했고 다른 반찬을 드래그 했을 때 바로 수정되는 방식

적용 후, 여러개가 등록 가능하고 중복 등록은 막고 종류는 3개까지만 등록되게 구현했다.


반찬 등록 타입을 string에서 object로 바꾸게 됐다. 쉬운 작업인 줄 알았는데 생각보다... 어려웠다. 그래서 좀 많이 헤맸다.
두 달 전에 작성했던 코드였는데 내가 이걸 왜 썼을까..? 이유를 까먹어 곰곰이 생각을 하기도 했고, 다시 드래그 이벤트를 작성했을 때의 버그들이 속속 나타났다. (a일에 등록한 반찬들이 b일에 그대로 복사된다던지.... 그런... 버그들...)


그 과정에서 zustand 공식문서를 조금 자세히 살펴볼 수 있었다.

나는 전역 상태관리를 위해 zustand를 사용하고 있었는데 말하기 많이 부끄럽지만 공식문서보단 구글링을 통해서 배운 것이 대부분이었다. 반성 중....


반찬 드래그가 끝날 때 반찬 state 초기화가 되지 않는 문제 같았다. setState를 사용할 때 이전 state 값을 판단해야 하나? 생각이 들어 zustand 이전 state를 활용하는 방법을 구글링 해봤는데 마땅한 결과가 나오지 않아 영어 가득한 zustand github를 들어가봤다.

README 코드를 확인해보는데 비슷하게 활용된 부분이 있어 냉큼 적용해봤다.

// 참고 코드

const createBearSlice = (set, get) => ({
  eatFish: () =>
    set(
      (prev) => ({ fishes: prev.fishes > 1 ? prev.fishes - 1 : 0 }),
      false,
      'bear/eatFish'
    ),
})

적용해봤으나 해결이 되지 않았고... 다시 생각해봤다.
state 초기화를 할 때 setSideMenu([]) 이렇게 빈 배열을 넣어주고 있었다. setSideMenu 함수는 어떻게 되어 있었을까?

setSideMenu: (sideMenu) => {
    set((prev) => ({
      sideMenu: [...prev.sideMenu, ...sideMenu],
    }));
  },

이러니.... 초기화가 되지 않고 있었다.
빈 배열이 인자로 들어가면 state가 초기화가 되지 않고 무조건 이전 state와 함께 state에 저장이 된다.
그래서 state가 쌓이고 쌓이고 쌓이고...... 다른 날짜에 새 반찬을 드래그해도 이전 날짜에 드래그 했던 모든 반찬들이 함께 state에 저장이 됐다.

100첩 반상 만들어보자~~~


열심히 고민해서 해결한 방법은 setState에 넣어주는 인자를 확인해서 state를 변경해주는 방식이었다.

setSideMenu: (sideMenu) => {
    set(() => ({
      sideMenu: sideMenu.length === 0 ? [] : sideMenu,
    }));
  },

만약 인자로 빈 배열이 들어왔을 때 (length === 0) 는 state를 초기화시키고, 그렇지 않으면 인자로 들어온 반찬 1개로만 state가 바뀌게끔 코드를 변경했다.


그러면 반찬 배열에 어떻게 계속 쌓일까?
...는 보여지는 메뉴 리스트 state를 복제해서 복제한 state 반찬 목록에 반찬 전역 state를 넣어서 복제한 메뉴리스트 state를 다시 setState에 넣어주는..... !@#$@#%!@# 그런 형식으로 진행된다.

//			   		이전 반찬들		  현재 반찬
menu.sideMenu = [...menu.sideMenu, ...sideMenu];

-> 이전 반찬들과 현재 반찬을 합쳐 현재 반찬들을 만든다 

잘 등록된다!




파이어베이스로... 배포! 🏆

파이어베이스 사용은 처음이어서 어떻게 배포가 진행되는지 잘 몰랐다. 프론트 따로 백 따로 배포를 해야하는 건가 싶어 일단 프론트는 vercel로 배포를 진행해둔 상태였다.
파이어베이스로 배포를 진행해보니 따로 배포를 진행할 필요 없이 한번에 배포되는 시스템인 것 같았다.

배포가 되고 로그인도 되고 식단표 저장, 불러오기도 되고 정말 신기했다. 나 혼자서 이렇게 배포까지 해볼줄이야... 1년 전엔 상상이나 해봤을까?
난 언제쯤 성장해보나 더 작아지는 느낌이 계속 들었는데 그래도 조금 성장했구나 느끼게 됐다.
그리고 이렇게 조금씩이라도 글을 써두니까 서비스가 어떻게 발전되어가고 있는지 너무나 잘 보여서 꾸준히 써야겠다는 다짐을 하게 됐다.

💃

profile
ฅ˘◡˘ฅ

0개의 댓글