-
Notifications
You must be signed in to change notification settings - Fork 4
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
[DEV] frame 페이지 이미지 불러오기 #39
Conversation
…en when refreshing
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.
고생했어요~!~~ LGTM~~
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.
찾아보니 Next.js가 SSR 방식으로 동작하기 때문에 window 객체를 사용하려면 클라이언트 측에서만 접근해야하기 때문에 useEffect안에 존재해야한다고 하는데, 똑같은 코드로 login에는 에러 없이 잘 작동해서 의문입니다(?)
이 부분에 대해서 답변 드리겠습니다.
문제점
window객체는 브라우저에서 동작하는 친구이기 때문에 서버사이드 렌더링에서는 항상 undefined
을 반환합니다.
이걸 막기 위해서 use clients
를 사용한다고 해도 또 다른 문제가 남아있습니다.
- use client는 서버 사이드 렌더링 컴포넌트가 아니라는 선언만 할 뿐이지 next의 기본 렌더링 방식인 일괄적으로 모든 페이지를 렌더링하는 방식은 막지 않습니다.
- 서버에서 해당 파일을 일괄적으로 렌더링하기 때문에 사용자가 해당 페이지를 렌더링하는 시점에는 이미 window가
undefined
라는 문제가 발생합니다. - 이 문제를 막기 위해서 웹 프레임워크는
lazy loading
을 지원합니다. 기존 방식처럼 한번에 모든 페이지를 불러오는 것이 아닌 필요할 때 마다 페이지를 불러오는 방식입니다. - lazy loading을 사용한다면 사용자가 이 페이지를 필요로 할때 비로소 해당 페이지가 로딩되기 때문에 window 객체를 정상적으로 받아올 수 있습니다.
해결방안
똑같은 코드라고 말씀하셨지만 유진님 코드랑 제 코드랑 결정적인 차이점이 맨 마지막 줄에 있습니다.
export default dynamic(() => Promise.resolve(LoginView), {
ssr: false,
});
VS
return (
<div className="flex w-full flex-col justify-start bg-background">
<PreviousPage target="/login" />
<p className="mb-3 text-center font-cafe24 text-xl text-primary-darkblue">
나의 프로필 목록
</p>
{list.length === 0 && <EmptyList />}
{!loading && list.length !== 0 && <ImageList list={list} />}
</div>
);
next에서 lazyloading을 지원하는 방식은 여러가지가 있지만 저는 다음과 같이 ssr:false option을 가진 프라미스 객체를 반환하는 형식으로 lazyloading을 구현했습니다.
- 그렇기 때문에 window객체를 useEffect 함수 안에 넣지 않더라도 사용할 수 있게 됩니다.
- 리액트나 next를 개발할때 저는 왠만하면 useEffect를 사용하지 않으려고 노력합니다. 이 함수 때문에 버그가 너무 많이 발생하고 디버깅도 힘들어지기 때문입니다.
- 그래서 저는 useEffect에 값을 넣지않고 어떻게
window
객체 문제를 해결할지 고민하고 나온 결과가lazy loading
입니다.
마무리
제가 window
객체의 값이 로딩되는 문제를 해결한 방법을 소개해드렸습니다.
물론 유진님이 문제를 해결한 방식이 더 마음에 드시면 그대로 머지하셔도 괜찮습니다. 저는 또 다른 해결 방안과 공부하면 좋을 토픽을 던져드린것 뿐입니다.
해당 문제 말고 다른 리뷰 밑에 남겨드렸으니까 확인해 주시면 좋을것 같습니다.
위 문제를 해결하기 위해서 필요한 참고 자료 링크 올려드리겠습니다.
next.js lazy loading
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.
일단 지금까지 push한 내용 리뷰했습니다. 에러메시지관련 몇가지 코멘트 남겨드렸습니다.
window 객체 문제는 해결되었는지 궁금하네요 항상 고생이 많으십니다
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.
변경사항 모두 확인했습니다!
뭔가 리뷰를 너무 많이 남겨드린 것 같은데, 혹시라도 너무 많다고 느끼시면 말씀해주세요
항상 고생 많으십니다 승인 했습니다
왕 감사합니다~~ |
Summary
Description
위의 로직을 위해 frame페이지에서 새로고침을 했을때
useAtom
을 이용해 list에서 선택된 이미지가 계속 유지되어야 하는데,useAtom
은 새로고침시 초기화가 되는 이슈가 있었습니다. 그래서useAtom
대신에 상태를localStorage
에 저장해주는atomWithStorage
를 사용하여 새로고침시에도 상태가 변하지 않도록 하였습니다.ai가 생성한 이미지를 불러오기 위해 이미지 목록 페이지에서 목록의 0번째 인덱스(가장 최근에 만들어진 이미지)를 사용해야해서 여기서도
atomWithStorage
를 사용하였습니다.const storedToken = window.sessionStorage.getItem('accessToken') || '';
이 부분이useEffect
바깥에 있을때 500에러가 발생해서useEffect
안에 있게 수정하였습니다.