프로젝트를 통한 배움 - (7)

응애 나 프론트애긔👶·2023년 1월 29일
0
post-custom-banner

FireStore 리팩토링

9와 8 어떤 것을 고를 것이냐.

MockData를 Firebase 홈페이지에서 직접 만들 수 있기 때문에 DB에 테스트 데이터를 저장 해놓고
이후 그 데이터를 불러와 페이지에 그리는 방식으로 했다.

Firebase를 처음 사용하는 상황이였기에 강의와 각종 블로그에서 어떻게 사용하지 예시 코드를 보며
테스트 데이터를 불러오는데 성공했다.

이후 Realtime Database를 사용하여 채팅 기능을 만들 때 한가지 문제를 발견했다.

Web version이 9가 있고 8이 있다.

두 버전의 문법이 달라 선택해서 사용하면 되는데
사용하는데 굳이 문제가 없는데 왜 리팩토링을 하냐 ?

이유는 9버전과 8버전의 config파일 import가 다른데 하나의 버전에서 받아와 관리에 용이하게 변경하기 위해서이다.

// Import the functions you need from the SDKs you need
import { initializeApp } from 'firebase/app';
import { getDatabase } from 'firebase/database';
import { getFirestore } from 'firebase/firestore';
import { getAuth } from 'firebase/auth';

const firebaseConfig = {
  apiKey: process.env.REACT_APP_API_KEY,
  authDomain: process.env.REACT_APP_AUTH_DOMAIN,
  projectId: process.env.REACT_APP_PROJECT_ID,
  storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_APP_ID,
  measurementId: process.env.REACT_APP_MEASUREMENT_ID,
};

const app = initializeApp(firebaseConfig);
const firestore = getFirestore(app);
const realtimeDatabase = getDatabase(app);
const auth = getAuth(app);

export { firestore, realtimeDatabase, auth };

FireStore은 v8 Realtime Database는 v9로 따로따로 관리하고 있었던 것을 v9로 버전을 통일 시켰다.

그럴싸한 슬라이드 효과

채팅 기능을 만들면서 채팅 목록을 모아서 볼 수 있는 리스트 페이지를 만드는 중에
채팅을 신고 또는 채팅방을 나갈 수 있는 버튼을 슬라이드형식으로 제작 해달라는 기획 요구가 있었다.

const ChatItem = () => {
  const mockData = [
    {
      id: 0,
      userName: 'A',
      lastMessage: '뉴진스 하입보이요.',
      notification: 0,
      active: false,
    },
    {
      id: 1,
      userName: 'B',
      lastMessage: '반갑습니다.',
      notification: 0,
      active: false,
    },
    {
      id: 2,
      userName: 'C',
      lastMessage: '안녕하세요.',
      notification: 1,
      active: false,
    },
    {
      id: 3,
      userName: 'D',
      lastMessage: '감사합니다.',
      notification: 3,
      active: false,
    },
  ];
  const [userState, setUserState] = useState(mockData);
  const copyUserState = [...userState];

  const clickSlideOption = (el: IUserData) => {
    if (!el.active) {
      copyUserState.filter(data => {
        data.active = false;
      });
    }
    el.active = !el.active;
    setUserState(copyUserState);

  };

  return (
    <>
      <ChattingItems>
        {copyUserState.map(el => {
          return (
            <ChattingItem key={el.id}>
              <UserName>{el.userName}</UserName>
              <LastMessage>{el.lastMessage}</LastMessage>
              {el.notification ? (
                <Notification>{el.notification}</Notification>
              ) : (
                <NotNotification />
              )}
              <DotsVerticalIcon
                onClick={() => {
                  clickSlideOption(el);
                }}
                className={el.active ? 'active' : 'inactive'}
              />
              {el.active ? (
                <SlideOptionsWrap className={el.active ? 'active' : 'inactive'}>
                  <SlideOption style={{ backgroundColor: 'red' }}>
                    신고하기
                  </SlideOption>
                  <SlideOption style={{ backgroundColor: 'white' }}>
                    나가기
                  </SlideOption>
                </SlideOptionsWrap>
              ) : null}
            </ChattingItem>
          );
        })}
      </ChattingItems>
    </>
  );
};

먼저 useState의 리스트를 복사해준다.
복사해주는 이유는 State의 불변성을 유지하기 위해서이며, 따로 복사해 덮어씌우는 형식으로 코드를 짰다.

이후 onClick 이벤트를 활용하여 더보기 아이콘을 클릭했을 때 element의 active를 확인하고 false일 때
다른 element들의 active를 false로 바꾸어주고 이벤트가 발생 된 element의 active를 true로 바꾸어준다.

이렇게 해야 다른 element의 더보기 아이콘을 클릭 시 기존에 클릭되어 열려있는 슬라이드를 닫을 수 있다.

이는 팀원의 피드백 중 사용자가 기존의 열려있는 슬라이드를 실수로 잘못 누를 수 있기 때문에
다른 슬라이드가 열릴 시 닫아주는 것이 사용자 측면에서 사용하기 편하다고 말씀해주었는다.

이를 반영하여 위와 같이 코드를 작성했다.

느낀점

파이어베이스 리팩토링 같은 경우는 기능 상에 문제는 없으나 버전을 통일하여
쉽게 에러상황 해결이나 유지보수에 도움이 될 거 같아 진행을 했다.

두번째로는 리스트의 슬라이드 효과인데 꽤나 마음에 드는 애니메이션이지만
웹보단 모바일 쪽에서 사용할 법한 효과이다.

또한 MockData를 객체로 만들어 사용하기 때문에 나가기 버튼의 이벤트를 아직까지 활성화 하지 않았다.
이유는 useRef를 사용하여 나가기 버튼을 사용해야하는데 서버 데이터를 가져오는 채팅 리스트는 post요청을 통해 수정을 해야 할 거 같아 미리 만들어 놓은 것은 무의미할 거 같기 때문이다.

post-custom-banner

0개의 댓글