👉 깃허브링크 바로가기
👉 배포링크 바로가기
유저 네임 입력 | 메시지 입력 | 답장 | 삭제 |
---|---|---|---|
이전에 처음으로 Portal을 사용해 모달창을 만들었었는데, 이번에는 조금 다르게 만들었다.
이전 프로젝트에서 모달창을 구현하면서 Portal을 사용한 코드는 다음 포스팅에 정리해두었다.
👉 포스팅 보러가기
기존 코드와 달라진 점이 있다면,
굳이 html 파일을 이동해 확인해보지 않아도, 해당 파일안에서 코드를 관리할 수 있어 유지 보수 및 가독성에서 더 좋을 것이라고 생각했기 때문이다.
//types.ts
export interface ModalPotalProps {
children: React.ReactNode;
}
//ModalPortal
import { useEffect } from 'react';
import ReactDOM from 'react-dom';
import { ModalPotalProps } from './types.js';
const Modal = ({ children }: ModalPotalProps) => {
const modalEl: HTMLDivElement = document.createElement('div');
useEffect(() => {
document.body.appendChild(modalEl);
return () => {
document.body.removeChild(modalEl);
};
}, []);
return ReactDOM.createPortal(children, modalEl);
};
export default Modal;
import React from 'react';
import { IoMdClose } from 'react-icons/io';
import { ModalProps } from './types';
import * as Styled from './styled';
function Modal({ children, onClose }: ModalProps) {
return (
<Styled.Background onClick={onClose}>
<Styled.ModalContainer>
<Styled.CloseButton>
{onClose && <IoMdClose onClick={onClose} />}
</Styled.CloseButton>
{children}
</Styled.ModalContainer>
</Styled.Background>
);
}
export default Modal;
이전에는 Recoil을 사용해 isOpened와 같이 모달창을 켜고 끄는데 사용하는 상태를 전역으로 관리했다. 하지만 이게 좋은 방식일까? 라는 고민을 했었다.
모달창이 사용되는 각 컴포넌트마다 ModalPortal과 Modal을 사용하는 것이 비효율적인 것 같았기 때문이다.
이번 프로젝트에서는 가장 처음과 삭제버튼을 누를 경우 2군데에서 사용되어서 분리했는데, 이전 프로젝트에서는 Modal 내부에서 컨텐츠 내용까지도 관리하고 싶었다.
하지만 그 모달이 결국 어디에서 사용되는지 찾기 힘들기 때문에... 이렇게 하는 것이 좋은 것 같다.
스타일 컴포넌트와 일반 컴포넌트의 구분을 위해서였다.
한 파일안에 별도로 styled파일을 만들어 스타일 컴포넌트를 정의했다.
이 styled.tsx에서 정의한 스타일들을 export하고,
//styled.tsx
import styled from 'styled-components';
export const ChatBubbleContainer = styled.div`
margin: 10px 0px 10px 0px;
display: flex;
`;
팀 내에서 협의한 대로 S라는 이름으로 import해 사용했다.
//index.tsx
import * as S from './styled';
<S.YourChatBubbleBlock>
<S.YourChatBubble>
<ChatBubbleContent message={message} mine={mine} />
</S.YourChatBubble>
<S.ChatBubbleUtilBox>
S.가 붙은 컴포넌트는 스타일 컴포넌트이고, 그렇지 않은 ChatBubbleContent는 기능적인 일반 컴포넌트라는 것을 한 눈에 구분할 수 있다.
나름대로 스타일 컴포넌트를 사용하면서 가독성을 개선하기 위해 이번 과제부터 달리한 방법이었는데, 좋은 방법이었다고 생각한다.
프로젝트 규모가 커질수록 확장성을 고려했을 때 하나의 컴포넌트는 하나의 역할을 하며 재사용이 가능하도록 잘게 쪼개는 것이 좋다고 생각한다. 그래서 이전 프로젝트에서는 아토믹 디자인으로 컴포넌트를 분할하였다.
그러나 이번 프로젝트는 규모 자체가 워낙 작았고, 팀원 4명이서 분담하기에도 어려워 주로 vsc liveshare로 동시에 작업하는 비중이 많았다. 그만큼 분할할 컴포넌트도 많지 않았고 프로젝트 진행 시점에서 효율적이지 않다는 판단이 들어 이번 과제에서는 사용하지 않기로 했다.
이번 과제에서는 별도의 Mock data 혹은 데이터 모델이 주어지지 않았다.
단 채팅창 접속 시 3명의 사람이 5건의 대화를 나눈 내역이 나타나야 한다는 조건이 있었기 때문에 해당 조건에 맞게 데이터 모델부터 정의해야 했다.
앞으로 작성할 코드에 영향을 많이 미치기 때문에 이 부분을 논의하는데 시간이 오래 걸렸다.
최종적으로 결정한 데이터 모델은 다음과 같았다.