-
Notifications
You must be signed in to change notification settings - Fork 1
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
[FE] 반응형 도입 #163
The head ref may contain hidden characters: "162-fe-\uBC18\uC751\uD615-\uB3C4\uC785"
[FE] 반응형 도입 #163
Conversation
zustand 설치 및 useMediaStore 생성 및 적용
[setMedia], | ||
); | ||
|
||
useLayoutEffect(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useLayoutEffect
); | ||
|
||
useLayoutEffect(() => { | ||
const observer = new ResizeObserver(observerBodySize); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
다른 게시글에서 봤던 반응형 컴포넌트는 엄청 간단한 형태였다는 것을 알게 되었습니다. useLayoutEffect나 ResizeObserver 모두 처음 봐서 신기했습니다. 고생하셨습니다!
|
||
const useMedia = () => { | ||
const media = useMediaStore((state) => state.media); | ||
const setMedia = useMediaStore((state) => state.setMedia); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useMediaStore을 이용해서 현재의 미디어 상태를 가져오고 useMediaStore을 이용해서 미디어 상태를 설정하는 함수를 가져오는군요.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네! Store라는 저장소를 바로 컴포넌트에서 사용하는 것보다 useMedia
처럼 커스텀 훅을 만들어 여러 기능을 추가하고 사용하는 것이 좋은(?) 패턴이라고 하더라고요!
|
||
if (!body) return; | ||
|
||
observer.observe(body); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분이 크기 변화 감시 역할을 하는군요. 'observer.observe가 body의 사이즈 변화 감지 -> 변화가 있다면 observerBodySize를 이용하여 ResizeObserverCallback 함수 실행하여 크기 재측정' 의 순서로 이뤄지는 게 맞을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네! 맞습니다 :) ResizeObserver
API를 활용하여 body의 사이즈를 항상 감지하고 있어요. 사이즈가 변화될 때 마다 observerBodySize
을 호출하게 되고요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
반응형을 위한 훅이라니 신선하네요! 👍 아무래도 스타일을 js로 직접 변경하는 것은 계산부담이 커질 수 있으니 반응형 레이아웃 변경은 웬만하면 styled-components 내에서 해결하고 스크롤이라든지 정말 기능적으로 반응형에 대한 로직이 필요할 경우에만 이 media
상태를 사용하는 것이 좋을 것 같군요 ㅎㅎ
++ PR 자세히 작성해주셔서 이해가 아주 잘 됐습니다 👍👍
import { create } from 'zustand'; | ||
|
||
type Media = 'mobile' | 'tablet' | 'desktop'; | ||
|
||
type State = { | ||
media: Media; | ||
}; | ||
|
||
type Action = { | ||
setMedia: (media: Media) => void; | ||
}; | ||
|
||
const useMediaStore = create<State & Action>((set) => ({ | ||
media: 'desktop', | ||
setMedia: (media) => set(() => ({ media })), | ||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zustand
는 안 써봤는데 recoil
이랑 비슷하고 간단한 것 같네요! 저도 공부하면서 써볼게요 👍
export const MEDIA_QUERY = { | ||
mobile: `@media(max-width: ${MEDIA_SIZE.mobile}px)`, | ||
tablet: `@media(max-width: ${MEDIA_SIZE.tablet}px)`, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
마음이 편안해지는 상수화,, 아주 좋습니다 👍 저도 이거 사용해서 반응형 만들어볼게요 :D
반응형 도입을 위한 작업을 진행했습니다. 내용이 많지 않아 아래의 설명으로 이번 작업에 대한 내용을 파악하실 수 있을거에요.
1. 기기에 따른 viewport 상수화
기기에 따른 viewport를 상수화했습니다.
src/constant/media
에서 확인할 수 있어요. 사이즈 기준은 여러 글을 참고하여 가장 많이 사용하는 너비로 정했습니다. 이 부분은 추후에 여러 의견을 듣고 수정할 수 있어요.2. media query 도입
현재 저희가 데스크탑 기준으로 스타일링을 하고 있습니다. 때문에 테블릿, 모바일 일 때의 스타일링을 추가해야 하는데요. 이를 위해 미디어 쿼리를 도입해야 합니다. 스타일 컴포넌트에서는 다음과 같이 미디어 쿼리를 사용할 수 있어요.
@media (max-width: 768px)
을 작성하고 스타일링을 하면 되는데요. 해당 구문의 의미는 가로의 너비가 최대 768px 일 때 까지 다음의 css를 적용해라입니다. 즉, 최대 너비가 768px보다 크면 적용이 안되고 그 이하일 때만 적용이 됩니다. 한 문장으로 설명하면768px 이하일 때 적용되는 css
입니다. 여전이 미디어 쿼리에서의 max, min은 헷갈리네요무튼 위와 같이 작성하여 각 페이지에서 가로 사이즈에 따른 스타일링을 하시면 됩니다. 하지만 매번
@media (max-width: 768px)
을 작성하면 헷갈릴 수도 있고 실수할 수도 있기 때문에 이것도 상수화를 했습니다.src/constant/media
에 있습니다. 다음과 같이 말이죠.여기서
MEDIA_SIZE
은 위 기기에 따른 viewport입니다. 이 상수화된 값을 가져와 다음과 같이 사용하면 됩니다.3. useMedia
위 훅도 만들었어요. 스타일에서 뿐 아니라 리액트 컴포넌트에서도 기기에 따라(가로 사이즈에 따라) 원하는 동작이나 렌더링되는 컴포넌트가 다를 수 있기 때문이에요. 해당 훅은 전역상태입니다. 전역상태로 만들기 위해 이번에
zustand
을 도입했어요. 다른 전역상태 라이브러리도 있지만zustand
가 훨씬 가볍고 사용법고 간단해서 선택했어요. 관심있는 쌤들은 한 번 공부해보세요! 저도 요세 하고 있습니다.아무튼 위를 통해 가로 사이즈에 따라
useMedia
가 반환하는 값이 달라집니다. 3개의 값이 있어요.mobile
,tablet
,desktop
이 그것이에요. 아래는 간단한 사용 예시입니다.