Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MISSION8/박건규 #50

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

geongyu09
Copy link
Collaborator

@geongyu09 geongyu09 commented Jun 26, 2024

들어가기 앞서, 바쁘신 와중에도 그동안 저희 스터디에 도움을 주신 모든 선배님들께 감사의 말씀 올립니다.

1. 구현 모습

image

https://last-mission.netlify.app/

2. 해결 과정

사용한 라이브러리 및 이유

  • supabase

    • 이번 미션을 수행하기 위해서 사용자의 데이터를 올리고 가져오는 등의 기술적 요구사항이 존재하였고, 이를 구현하기 위하여 서버 및 데이터베이스 기술이 필수적으로 적용되어야 했습니다.
    • 하지만, 그리 복잡한 요구사항은 아니었으므로, 직접 데이터베이스를 연결하는 등의 과도한 엔지니어링은 필요하지 않을 것이라 생각하였습니다.
    • 또한 사진 데이터를 다루기로 하여, storage를 같이 사용할 수 있는 BaaS를 사용하기로 하였습니다.
    • (여기에서 drizzle과 같은 orm을 적용하는 것 또한 오버 엔지니어링이라 생각하였습니다. )
  • tanstack query (react query)

    • 서버로부터 받아오는 정보들은 블로그 특성상 자주 바뀌지 않는 데이터일 것이라 생각하였습니다.
    • 이에 따라서 한번 요청한 값을 캐싱해두는 방식으로 불필요한 요청을 줄일 필요가 있을 것이라 생각하였습니다.
    • 이를 통해 서버의 상태를 관리해주는 react query를 사용하기로 하였습니다.

모달

  • 이 경우 모달을 띄워주는 리액트의 createPortal를 사용하였습니다.

image

  • 모달을 띄워야 하는 곳이 여러 곳이라면 해당 로직은 반복될 것이라 예상하였고, 이를 따로 뺌으로서 코드의 반복을 줄이고자 하였습니다.
import { createPortal } from "react-dom";

export default function Portalcreater({ children }) {
  return children ? createPortal(children, document.body) : null;
}
  • 사용하는 곳에서는 아래와 같이 사용할 수 있습니다.
      {modalOn && (
        <Portalcreater>
          <Contentmodal closeModal={closeModal} modalOn={modalOn} />
        </Portalcreater>
      )}

반복되는, 유사한 스타일의 버튼 컴포넌트

  • 사이트를 보면 유사한 스타일이 반복되는 버튼 컴포넌트가 존재하였습니다.
    image
    image

  • 이를 따로 컴포넌트로 뺴서 관리하기로 하였습니다.

const buttonColor = {
  primary: {
    textColor: "#20c997",
    borderColor: "#20c997",
  },
  default: {
    textColor: "#8a8a8a",
    borderColor: "#8a8a8a",
  },
};

export default function StyledBtn({
  buttonText,
  onClickHander,
  color = "default",
}) {
  return (
    <StyledButton $color={color} onClick={onClickHander}>
      {buttonText}
    </StyledButton>
  );
}

const StyledButton = styled.button`
  padding: 0.5rem 1rem;
  color: ${({ $color }) =>
    buttonColor[$color]?.textColor || buttonColor.default.textColor};
  background-color: white;
  border: 1px solid
    ${({ $color }) =>
      buttonColor[$color]?.borderColor || buttonColor.default.borderColor};
  border-radius: 100px;
  cursor: pointer;
`;
  • 다만 이는 들어가는 글자나 스타일이 완벽하게 동일하지는 않았기에, 각 상황에 맞추어 각기다른 스타일을 제공해야 했습니다.
  • 이를 구현하기 위한 방법 중 props를 통해서 style값을 그대로 받아오는 것은 사이드이팩트가 너무나도 큰 방법이라고 생각이 들었습니다.
  • 컴포넌트 내에서 어느정도 받을 수 있는 값을 한정지을 수 있으면, 본인 스스로 사이드 이팩트를 관리할 수 있는 꽤 괜찮은 컴포넌트가 될 수 있지 않을까? 생각하였습니다.
  • 이를 위해 buttonColor 라는, 사용될 값만 저장해둔 상수를 선언하여 구현하였습니다.

문제상황

  • 컨텐츠를 클릭하여 모달을 띄운 후, 배경을 누르면 모달이 닫히도록 구현을 하였습니다.
  • 로직상 문제는 없어보였지만, 이는 동작하지 않았습니다.
export default function ContentModal({ id, closeModal }) {
//생략
const handleModalClose = (e) => {
  // e.stopPropagation(); //click을 해도 closeModal() 함수가 정상적으로 되지 않음.
  closeModal();
};

return (
  <StyledContentModal>
    <button id="modal-background" onClick={handleModalClose} />
    <section id="modal-main">

     {/* 모달 내용 */}

    </section>
  </StyledContentModal>
);
}
  • 혹시나 하는 마음에 이벤트 버블링을 막는 로직을 추가하게 되었고, 결과적으로 잘 동작하게 되었습니다.
  • 아마 이벤트가 해당 모달을 여는 곳까지 전달되어, 닫힌 후 열린 것이 아닌가? 하는 생각을 하게 되었습니다.
  • 다만 이는 body 하위에 위치하도록 했는데, 어떻게 이벤트가 전달되었는지.. 알 수가 없네요. 이와 관련해서 원인에 대해 알고 싶습니다..
참고 사진 버블링을 막지 않은 경우

bug

버블링을 막은 경우

good'


3. To 리뷰어에게

  • 모달 관리와 관련해서 해당 방법이 저의 수준에서 최고의 코드라고 생각이 듭니다. 현업에서는 정말 다양한 모달이 존재하는 서비스를 마주할 수 있을 것 같은데, 컴포넌트를 관리하는 좋은 방법이 있는지도 궁금합니다!
  • 버블링 관련 문제 상황을 마주하게 되었는데, 저의 지식이 부족한 탓에 아직 해당 원인을 찾지 못하였습니다. 이와 관련하여서 어떻게 접근해야 할지에 대해 감이 잡히지 않습니다. 이에 조언을 구하고자 합니다.
  • 추가적으로 코드에서 수정할 부분이 있는지 궁금합니다!

스터디 느낀점 이번에 처음으로 스터디에 참여해보고, 스터디를 운영해보게 되었습니다. 이 과정에서 많은 어려움도 있었지만, 주변 선배님들께서 정말 많이 도와주셔서 이렇게 끝까지 마무리 할 수 있었던 것 같습니다. 이에 더불어서 굳이 저희 스터디를 도와줄 의무가 없음에도, 저희를 좋게 생각해주시고, 끝까지 저희 스터디에 도움을 주셨던 모든 선배님들에게 감사함을 표합니다. 그리고 스터디 끝까지 함께 해준 스터디 팀원분들에게도 너무나도 고맙습니다.

저희가 너무나도 과분하게 많은 것을 받음을 인지하고 있고, 덕분에 정말 많이 성장할 수 있었던 것 같습니다.
저희가 받은만큼 저희도 성장하여 도움을 줄 수 있는 사람이 되도록 하겠습니다.
정말로 감사드립니다.

환경설정을 합니다
- 사용하지 않는 파일을 제거합니다.
- reset css 를 적용합니다.
supabase api 를 추가합니다.
상태관리를 위하여 react query 를 추가하였습니다.
content 영역의 style를 추가합니다.
- 기본 image 를 추가합니다.
- 컴포넌트에 css 를 추가합니다.
- 헤더에 새 글작성 버튼을 추가합니다.
- 모달을 추가합니다.
  - 모달을 만들어주는 로직은 재사용이 가능하므로 이를 따로 컴포넌트로 빼두었습니다.
  - 모달 컴포넌트의 책임이 creator 일지, 아니면 컴포넌트를 띄우는 로직이 들어있는 곳인지에 대한 고민 -> 모달을 띄우는 곳에서 책임을 가지도록 하였습니다.
p 태그를 pre 태그로 변경합니다.
padding 간격을 조정합니다.
반복되는 컴포넌트를 재사용 가능하도록 수정
@geongyu09 geongyu09 added the mission 미션 입니다! label Jun 26, 2024
@geongyu09 geongyu09 requested a review from GiPyoo June 26, 2024 13:11
@geongyu09 geongyu09 self-assigned this Jun 26, 2024
Copy link

vercel bot commented Jun 26, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
donut-study ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 26, 2024 1:12pm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mission 미션 입니다!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant