묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Next + React Query로 SNS 서비스 만들기
게시물 업로드 시 userId가 undefined로 들어가는 오류
안녕하세요.게시물 업로드 요청 시 500 Internal Server Error 에러가 발생합니다.현재 코드에는 쿠키도 함께 전달되고, 네트워크 탭에서 확인해보면 formData 값도 정상적으로 전송되는 것으로 보입니다. const onSubmit: FormEventHandler = (e) => { e.preventDefault(); // formData 객체에 값 넣기 const formData = new FormData(); formData.append("content", content); preview.forEach((item) => { if (item) { formData.append("images", item.file); } }); // 전송 fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/posts`, { method: "post", credentials: "include", body: formData, }); };그런데 서버에서는 userId가 undefined로 들어가고 User 정보가 없다(?)는 오류가 발생합니다.다른 분들의 Internal server error 관련 질문을 살펴봐도, 이 문제가 프론트에서 확인할 수 있는 부분인지 잘 구분이 되지 않아 질문드립니다.제가 어디를 중점적으로 확인해보면 좋을까요?
-
미해결Next + React Query로 SNS 서비스 만들기
useSuspenseQuery 사용 시 SSR 401 이슈 관련
안녕하세요 강사님 좋은 강의 잘 듣고 있습니다!useSuspenseQuery를 사용 중에 고민이 생겨서 질문 드립니다.제가 구현하고 있는 프로젝트의 대부분 API는 인증이 필요합니다.refresh token은 http only 쿠키로 관리하고, access token은 쿠키에 저장하고, 요청 헤더에 넣어 인증을 하고 있습니다.useSuspenseQuery를 사용하는 페이지에서 SSR 단계에 401 에러가 발생합니다.이후 CSR 전환 시에는 정상적으로 데이터를 불러와 화면은 최종적으로 렌더링됩니다.해당 페이지를 dynamic import로 CSR 강제하면 401이 발생하지 않습니다. 제가 추정한 원인은클라이언트 컴포넌트 내부라도 초기 렌더링 시 SSR 패스에서 useSuspenseQuery가 실행되어 서버에서 API 요청이 발생.이때 공통 axios 인스턴스가 클라이언트 전용 방식으로 쿠키를 읽어 헤더에 토큰을 주입하도록 구현되어 있어, 서버 환경에서는 토큰을 읽지 못해 401이 발생하는 것으로 판단했습니다. 해결을 위해 시도한 방법prefetchQuery +useSuspenseQuery 조합으로, prefetchQuery 단계에서 next/headers를 통해 서버 환경에서 토큰을 읽어 주입하면 401이 사라졌습니다.다만, 모든 useSuspenseQuery 호출 지점마다 prefetchQuery를 추가하는 것은 과도하다고 느껴 대안을 모색 중입니다. 질문 사항왜 SSR에서 실행되나요?클라이언트 컴포넌트 내부에서 호출하는데도 useSuspenseQuery가 SSR 렌더링 단계에서 동작하는 메커니즘을 정확히 이해하고 싶습니다.useSuspenseQuery의 단점/주의점강의에서는 주 사용을 권장해 주셨는데, 모든 데이터 관리에 useQuery 대신 useSuspenseQuery 사용하는게 좋은건지 실제 서비스에서 고려해야 할 단점이나 주의사항이 궁금합니다.401을 피하는 권장 패턴제 환경처럼 서버에서 토큰을 읽지 못해 401이 나는 경우,제가 시도한 방법 인prefetchQuery 적용 외에 권장되는 표준 패턴이 있을까요?prefetchQuery를 여러 곳에서 사용할 때의 리스크여러 페이지/쿼리에서 prefetchQuery를 널리 적용하면 TTFB 지연, 직렬화된 캐시의 HTML 페이로드 증가, 중복 호출 등의 문제가 커질 수 있을까요?그렇다면 적절한 적용 기준이나 완화 전략이 궁금합니다.그리고 어떤 기준으로 prefetchQuery를 적용하면 좋을지도 궁금합니다.문서와 블로그, GPT 등을 찾아봤지만 명확히 정리하기 어렵고, 제가 질문을 드릴 수 있는 최고 전문가라고 생각하여 의견을 여쭙니다.긴글 읽어주셔서 감사합니다! 아래 에러가 발생하는 예시 코드 첨부 드립니다. (APage를 CSR로 강제하면 에러 미발생)import Spinner from "@/components/common/spinner/Spinner"; import A from "@/components/pages/A"; import { Suspense } from "react"; import { ErrorBoundary } from "react-error-boundary"; interface APageProps { params: { id: string; }; } export default async function APage({ params, }: APageProps) { const { id } = params; const parsedId = parseInt(id); return ( <ErrorBoundary fallback={<div>에러가 발생했습니다</div>}> <Suspense fallback={<Spinner fullscreen />}> <A id={parsedId} /> </Suspense> </ErrorBoundary> ); }"use client"; import { useGetAList } from "@/api/A/queries/useGetAList"; interface AProps { id: number; } export default function A ({ id }: AProps) { const { data: probiomeList } = useGetAList(id); // 생략 import { queryKeys } from "@/constants/queryKeys"; import { UseSuspenseQueryCustomOptions } from "@/types"; import { useSuspenseQuery } from "@tanstack/react-query"; import { getAList } from "../A"; import { AList } from "@/types/A"; export function useGetAList( id: number, queryOptions?: UseSuspenseQueryCustomOptions<AList> ) { return useSuspenseQuery({ queryFn: () => getAList(id), queryKey: [ queryKeys.A.BASE, queryKeys.A.GET_A_LIST, id, ], ...queryOptions, }); }
-
미해결Next + React Query로 SNS 서비스 만들기
리액트 쿼리 useinfinitequery 무한스크롤 구현 시 페이지가 이동할 경우 데이터가 보존되게 할 수 있나요??
더보기 버튼 클릭 시 페이지 이동 (page=1 -> page=2) + 무한스크롤 구현 기능 구현이 필요해서 아래와 같이 구현해보았는데 어쩔땐 되고 어쩔땐 안되더라구요...만약 데이터를 10개씩 불러올 경우 10개 -> 20개 -> 30개 -> 40개 이러다 갑자기 다시 10개가 됩니다...원래 useInfiniteQuery 무한스크롤 구현 시 페이지이동하면서 기존 데이터를 보존하는 방법이 불가능한건지 아님 제가 코드를 잘못짠건지 궁금합니다... const useInfiniteQuery = (params: Params) => { const searchParams = useSearchParams() const page = searchParams.get('page') return useInfiniteQuery({ queryKey: [CONTENTS_KEY, params], queryFn: ({ pageParam }) => { return getContentsApiClient({ ...params, ...outLinkParams(), page: Number(pageParam) }) }, getNextPageParam: (lastPage, _, lastPageParam) => { // 마지막 page라면 hasNextPage가 false const lastPageNumber = Math.ceil(lastPage.totalCount / (params.size || 10)) if (lastPageNumber === lastPageParam) { return undefined } return Number(lastPageParam) + 1 }, initialPageParam: Number(page) || 1, placeholderData: keepPreviousData, }) } //더보기 버튼 // 클릭 시 페이지 이동 function AddMore({ fetchNextPage, totalPages }: { fetchNextPage: () => void; totalPages: number }) { const searchParams = useSearchParams() const pathname = usePathname() const params = new URLSearchParams(searchParams.toString()) const pageNo = Number(searchParams.get('page') || 1) params.set('page', (pageNo + 1).toString()) if (totalPages === pageNo) return null return ( <div className={cn('wrap')}> <Link className={cn('link')} href={`${pathname}?${params.toString()}`} onClick={fetchNextPage} scroll={false} > <span className={cn('label')}>더보기</span> </Link> </div> ) } 강의 잘 듣고있습니다. 감사합니다! 참고로 백엔드는 문제가 없습니다.
-
미해결Next + React Query로 SNS 서비스 만들기
폴링이 필요없는 이유
폴링이 필요없는 시대라고 하셨는데 그 이유가 궁금합니다
-
미해결Next + React Query로 SNS 서비스 만들기
next Request Memoization과 react cache
next.js에서 제공하는 Request Memoization 기능은 같은 엔드포인트 경로로 여러 개의 요청이 들어왔을 때 하나의 요청으로 캐싱해주는걸로 알고있습니다. 이와 관련해서 3가지 궁금증이 있습니다. Request Memoization 기능은 같은 페이지 한정인가요. 아님 프로젝트 전역에 적용되는걸까요?? 예를 들어 /dashboard 와 /home 두 페이지 모두에서 getUserInfo 라는 fetch 함수를 호출한다면 이 경우도 Request Memoization 이 적용되는건가요.만약 같은 엔드포인트지만 넘겨주는 파라미터가 다를 경우도 Request Memoization이 적용되나요?axios를 사용한다면 Request Memoization 기능을 활용할 수 없는걸로 알고있는데 react에서 제공하는 cache 함수를 사용하면 동일한 효과를 기대할 수 있나요? 감사합니다!!
-
미해결Next + React Query로 SNS 서비스 만들기
seo 최적화 기준은 데이터 fetching인가요 아님 데이터 렌더링인가요?
seo 관련해서 궁금한게 있습니다.seo 최적화라는게 크롤링 봇이 서버에서 렌더링된 html을 크롤링하고 인덱싱하는걸로 알고 있습니다. 만약 서버 fetch 를 했지만 data 자체는 렌더링하지 않은 경우는 크롤링 봇이 어떻게 인식을 하는지 궁금합니다. 예를 들어 서버 fetch를 했지만 아래와 같이 서스펜스 역할하는 로직으로 인해 클라이언트 환경에서 hydrate 된 이후에 데이터가 렌더링된다면 서버에서 fetch는 이루어졌지만 렌더링된건 아니기 때문에 크롤링봇이 데이터를 인식하지 못하게 되는걸까요?? export function ConditionalClientWrapper({ children, fallback, }: ConditionalClientWrapperProps) { const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); if (!mounted) return fallback ?? null; return children; } <ConditionalClientWrapper fallback={<Loading />}> //dataList에서 서버 fetch 가 이루어집니다. <dataList /> </ConditionalClientWrapper> SEO 최적화를 위한 조건이 데이터 렌더링인지 단순 서버 fetch 만하면 되는건지 궁금합니다. 추가로 리액트 쿼리의 prefetch를 사용하면 seo 최적화를 가질 수 있는건가요?? 감사합니다!
-
미해결Next + React Query로 SNS 서비스 만들기
next.js 서버fetch 에러 fallback ui 구현 방법
next 공식문서를 살펴보면 단순 서버 fetch (서버액션x) 관련 에러 핸들링 방법은 딱히 안나와 있는 것 같아 질문드립니다.만약 SectionA, SectionB, SectionC 서버 컴포넌트 내에서 각각 서버 fetch가 일어난다 가정했을 때 SectionB에서만 요청이 실패했다면 SectionB 영역만 fallback ui를 띄우고 나머지 SectionA, SectionC는 정상적으로 데이터를 렌더링하도록 구현하는 방법이 없을까요? error-boundary 라이브러리는 클라이언트 환경에서만 사용가능해 서버 컴포넌트에선 사용할 수 없고 next 내부적으로 설계되어있는 에러 바운더리(error.js 등)는 전역에러를 캐치하는 걸로 알고있습니다. 때문에 페이지 내 특정 영역만 fallback ui를 띄우는 용도는 아닌 것 같더라구요.혹시 다른 방법이 있나 궁금합니다 감사합니다!!
-
미해결Next + React Query로 SNS 서비스 만들기
프레임워크 여론 파악법
next 15, app router를 알아갈수록 어째.. 제 취향에 안맞거나 제 서비스에 적용하기에 불리한 점들이 많은데요 저만 그런건지 궁금하기도 해서, 특정 프레임워크에 대한 평가나 여론을 알아보는 팁 같은게 있으신지 궁금합니다. 지금은 유튜브 검색해서 상위노출 영상 몇개에 의존하는데 모수가 부족한 느낌입니다 정석적으론 각 프레임워크 공식문서를 보고 그 특성들을 이해해 자기 서비스에 맞는걸 스스로 판단하는 것이겠지만, 그래도 집단지성에 기대고 싶네요ㅎ
-
미해결Next + React Query로 SNS 서비스 만들기
필터옵션이 많은 페이지에서 서버 fetch를 하는게 맞는걸까요??
next 공식문서에서 서버 fetch를 권장하고 있지만필터옵션이 다수 포진된 페이지에서도 서버 fetch를 해야할까 의문점이 듭니다.필터 버튼 하나 누를때마다 다시 fetch 해야하니까 route.push나 replace 할 수 밖에 없는데 이게 과연 좋은 방법인가 의구심이 듭니다.리액트 쿼리를 사용하는게 더 나을지, 서버 fetch를 사용하는게 나은지 선생님의 의견이 궁금합니다. 추가로 window.history.replaceState webAPI를 사용하면 단순 url만 변경하고 페이지 로드나 컴포넌트 리렌더링은 일어나지 않는걸로 알고 있는데요. 근데 리액트 쿼리로 클라이언트 fetch 할 땐 window.history.replaceState 로 url만 변경해도 다시 fetch가 되더라구요?? 어떤 원리로 동작하게 되는지 궁금합니다!
-
미해결Next + React Query로 SNS 서비스 만들기
서버 fetch suspense 로 감싸고 새로고침 시 잠시 빈 화면이 노출된 후 fallback ui가 노출됩니다.
autoexport default function Weekday() { return ( <Suspense fallback={<WeekdayBannerLoading />}> <WeekdayMiniBanner /> </Suspense> ); }export default function WeekdayMiniBanner() { const { banners } = use(getBanners( params )); if (banners.length === 0) return null; return ( <div className={cn('wrapper')}> <WeekdaySwiper data={banners} /> </div> ); }이런 식으로 코드를 짰는데요. 해당 페이지를 새로고침하면 초기엔 컨텐츠영역 아무것도 노출되지않다가 잠깐 fallback ui가 노출되고 fetch가 완료되면 컨텐츠를 노출시킵니다. suspense는 promise가 pending 중일 때 promise를 catch해서 fallback ui 를 노출시키는걸로 알고 있는데 왜 새로고침 시 페이지 초기로드단계에선 빈화면이 노출되는지 궁금합니다... 아님 제가 잘못 설계한 걸까요..?? 리액트 공식문서 suspense 예시 코드에선 버튼 누르자마자 바로 fallback ui를 노출시키는데 말이죠... 참고로 WeekdaySwiper 내부는 react swiper로 구성되어있습니다! (클라이언트 컴포넌트)
-
미해결Next + React Query로 SNS 서비스 만들기
template.tsx 내 서버fetch 응답값과 클라이언트 컴포넌트 상태값 싱크가 맞지 않는 이슈
아래 코드와 같이 template.tsx에서 서버fetch 후 사용처인 클라이언트 컴포넌트로 props 넘겨주도록 세팅해놓았습니다. //template.tsx 자식 컴포넌트 export default async function Sidebar() { const { isSucceed, body } = await getUserGetInfo(params); return ( <SidebarLayout> <GiftIcon isNewGift={!!body?.info.new_gift} /> 'use client' export default function GiftIcon({ isNewGift }: { isNewGift: boolean }) { const { onClose } = useModal('SIDEBAR'); return ( <Link className={isNewGift ? cn(st['active']) : ''} /// <Icon type="Present" title="선물함" w={25} h={25} /> 이 상태에서 next 페이지 이동 시 서버fetch는 리렌더링 되는것을 확인했는데이상하게 클라이언트는 리렌더링이 되지 않습니다. 즉 서버 응답값은 상태가 바뀌어도 클라이언트 상태값은 바뀌지 않더라구요... 왜 이런걸까요ㅠㅠㅠ
-
해결됨Next + React Query로 SNS 서비스 만들기
Auth.js 사용 시 authorize 함수가 호출되지 않습니다
안녕하세요. 먼저, Next.js 를 입문한지 얼마 되지 않아 질문이 서툴 수 있는 점 양해 부탁드립니다..!현재 msw 세팅을 완료 했고, Auth.js는 공식문서를 참고하여 5버전과 동일하게 auth.ts 파일을 아래와 같이 작성하였습니다.// auth.ts import NextAuth from "next-auth"; import Credentials from "next-auth/providers/credentials"; export const { handlers, signIn, signOut, auth } = NextAuth({ pages: { signIn: "/i/flow/login", newUser: "/i/flow/signup", }, providers: [ Credentials({ authorize: async (credentials) => { const response = await fetch( `${process.env.NEXT_PUBLIC_BASE_URL}/api/login`, { method: "POST", body: JSON.stringify({ username: credentials.username, password: credentials.password, }), headers: { "Content-Type": "application/json" }, }, ); if (!response.ok) { return null; } const user = await response.json(); console.log("로그인 정보", user); return { id: user.id, name: user.nickname, image: user.image, ...user, }; }, }), ], });// @modal/(.)/i/flow/login/page.tsx const onLogin = async () => { try { await signIn("credentials", { username: id, password, redirect: false, }); router.replace("/home"); } catch (err) { console.error(err); setMessage("아이디와 비밀번호가 일치하지 않습니다."); } };문제는 authorize 함수 내 콘솔이 찍히지 않는 것으로 보아, 해당 함수가 아예 실행되지 않는 것 같습니다.회원가입하지 않은 아이디와 비밀번호를 입력해도 로그인이 되고 /home 으로 이동합니다. home으로 이동 후 session 응답 값은 null이고 쿠키에도 auth 토큰이 저장되지 않습니다.그리고 터미널에는 첫번째 이미지 처럼 에러 메세지가 뜨고, 브라우저 콘솔에는 두번째 이미지와 같은 메세지가 뜹니다. // handlers.ts http.post(`${baseUrl}/api/login`, () => { console.log("로그인"); return HttpResponse.json(User[1], { headers: { "Set-Cookie": "connect.sid=msw-cookie; HttpOnly; Path=/", }, }); }),현재는 MSW가 요청을 제대로 가로채지 못하고 있는 것 같다는 의심이 드는데, 어디를 우선적으로 점검해야 할지 잘 모르겠습니다..초보라 부족한 점이 많지만, 방향을 잡을 수 있도록 힌트나 조언 주시면 정말 감사하겠습니다 ㅠㅠ
-
미해결Next + React Query로 SNS 서비스 만들기
next.js 에서 로그인에 관하여
안녕하세요 제로초님, 로그인 관련해서 어려움이 있어서 질문드립니다. 현재 사용하고 있는 기술 스택은 다음과 같습니다.프론트 : next.js/백엔드 : express 로그인을 구현했고 백엔드에서 토큰을 만들어서 refreshToken 은 httpOnly cookie 에,accessToken 은 응답 바디에 넣어서 보내주도록 만들었습니다. 라이브러리 사용하지 않고, next.js 에서 로그인 api 호출하고 token 은 전역으로 관리하고, 토큰 만료시 토큰 재발급하고, 새로고침 시에도 로그인이 유지되도록(httponly 쿠키로) fetchWrapper 을 따로 만들었습니다. -> fetch 은 axios 와 달리 interceptor 같은거 못사용하니까요 하지만 이는 클라이언트 컴포넌트에서만 가능하고, 서버에서는 토큰 만료시 재시도 로직이 불가능하다는 것을 알게되었습니다. 코드도 지저분해지는 것같고.. 그래서 다른 해결책이 있나해서 이 강의의 로그인 부분을 보고있습니다. 근데 auth,js 는 env 에 jwt secret 키를 넣어야하는걸 보니 클라이언트에서 토큰을 관리하는 것 같더라구요 제 생각은 auth.js 는 백엔드 서버에서 쿠키를 관리하는 방식과 함께 사용하기에는 맞지 않다는 느낌을 들었습니다. 그래서 next.js 에서 로그인 및 권한 관리를 쉽게 사용하려면 결국 auth.js 를 사용해야만 하는 것인지.... 궁금합니다. 그렇게된다면 백엔드에서 토큰 만드는 로직을 없애는 것이 맞는지 궁금합니다. 감사합니다.
-
미해결Next + React Query로 SNS 서비스 만들기
Next의 route handler에 대한 질문이 있습니다.
안녕하세요 Next app router 관련해서 질문드립니다.현재 사이드프로젝트에서 route handler를 적극활용하고 있는데요.제가 인프라나 백엔드 관련 지식이 없다보니 좀 헷갈리는게 있습니다. 현재 저희 서비스에서 특정 API는 클라이언트 컴포넌트에서 route handler로 API 호출 -> route handler에서 외부 백엔드 API 호출이런 형태로 사용되고 있는데요, 이때 실제로 route handler 서버가 아래의 사진 중 어느 형태로 운용되는 것인가요? 즉, Next 프로젝트를 배포했을 때 각 유저마다 route handler 서버가 할당되는 것인가요? 아니면 모든 유저의 요청을 오직 하나의 route handler서버에서 대응하는 것인가요? 아니면 이게 배포 환경에 따라 달라지는것인가요?
-
미해결Next + React Query로 SNS 서비스 만들기
게시판 리스트 만들때 use client를 어디서부터 집어넣어야할지 모르겠습니다
<리스트> <레코드1/> <레코드2/></리스트> 일 경우… 리스트단에서 use client로 한 후 zustand에서 리스트 자체를 통으로 관리해야하는가?각각의 레코드에 use client를 한 후 데이터를 받으면 zustand에 리스트를 만들어 레코드별로 hash(Map)으로 등록해 관리해야하는가? 레코드에는 좋아요, 조회수 등이 표시됨. 제 생각은1번은 SEO가 중요한건 각각 레코드 (상세페이지) 이므로 zustand에서 통으로 넣어 관리하면 되니 구현 및 데이터 신뢰도에서는 나아보이는데 하나바뀌면 전부 렌더링되니까 애매한거같고2번은 서버에서 모두 다 가져와서 초기속도는 빠르고 seo에 좋으나 zustand에 통으로 못넣고 데이터 자체를 내가 직접관리하는 구조라 구현 및 데이터 신뢰 측면에서는 골치아플거같은데… 무엇이 일반적인 구현방식인지 모르겠습니다. 도와주세요 ㅠㅠ
-
미해결Next + React Query로 SNS 서비스 만들기
프라이빗 폴더를 해야 하는 이유가 모호한 것 같아요.
프라이빗 컴포넌트로 잡은 것과 그냥 컴포넌트로 잡은 것의 차이가 없지 않나요?컴포넌트를 예로 강의를 찍어 주셨는데 폴더만 더 늘어나고 좋은 예는 아닌듯합니다.프라이빗 폴더가 어떨 때 왜 필요한지를 알려주는게 더 교육적일 것 같아 글 남깁니다.컴포넌트 자체가 재사용성을 갖는 것이기에 내부 구성요소만 표기하는 프라이빗은 큰 의미가 없을 것 가은데요. 컴포넌트 외 폴더라고 해도 와닿지는 않습니다. 어차피 컴포넌트로 사용하면 uri 에도 잡히지 않고 말이죠. 전체적으로 폴더 구조만 더 복잡해지는 것 같아요
-
미해결Next + React Query로 SNS 서비스 만들기
vanilla-extract 못찾는 문제
안녕하세요~ 강의 잘 보고 있습니다! vanilla-extract 적용해보려고 하는데 패키지 설치하고 config설정까지 했는데 해당 에러가 나서 질문드립니다. next.config.ts파일과 globalTheme.css.ts, layout.ts중에 문제가 있을까요?? 파일 이름도 문제가 없고 코드 그대로 사용했는데도 해당 에러가 나서 next15에서 vanilla-extract 적용을 할 수 없는건지 궁금해서 여쭤봅니다.. 감사합니다// package.json// next.config.tsimport type { NextConfig } from "next"; const { createVanillaExtractPlugin // eslint-disable-next-line @typescript-eslint/no-require-imports } = require('@vanilla-extract/next-plugin'); const withVanillaExtract = createVanillaExtractPlugin(); const nextConfig: NextConfig = { /* config options here */ experimental: { serverActions: { bodySizeLimit: '10mb', // Set the body size limit for server actions } }, async rewrites() { return [ { source: '/upload/:slug', destination: `${process.env.NEXT_PUBLIC_BASE_URL}/upload/:slug`, // Matched parameters can be used in the destination }, ] }, }; module.exports = withVanillaExtract(nextConfig); // globalTheme.css.tsimport {assignVars, createGlobalTheme, createGlobalThemeContract, globalStyle} from "@vanilla-extract/css"; export const global = createGlobalThemeContract({ background: { color: 'bg-color' }, foreground: { color: 'fg-color' }, }) const whiteGlobalTheme = { background: { color: 'rgb(255, 255, 255)' }, foreground: { color: 'rgb(0, 0, 0)' }, } const darkGlobalTheme = { background: { color: 'rgb(0, 0, 0)' }, foreground: { color: 'rgb(255, 255, 255)' }, } createGlobalTheme(':root', global, whiteGlobalTheme); // 실제 적용 globalStyle(':root', { '@media': { '(prefers-color-scheme: dark)': { vars: assignVars(global, darkGlobalTheme), } } }) globalStyle('*', { boxSizing: 'border-box', padding: 0, margin: 0, }) globalStyle('html', { '@media': { '(prefers-color-scheme: dark)': { colorScheme: 'dark', } } }); globalStyle('html, body', { maxWidth: '100dvw', overflowX: 'hidden', }) globalStyle('body', { color: global.foreground.color }) globalStyle('a', { color: 'inherit', textDecoration: 'none', }) // layout.tsximport type {Metadata} from 'next' import {Inter} from 'next/font/google' import './globalTheme.css'; import {MSWProvider} from "@/app/_component/MSWComponent"; import AuthSession from "@/app/_component/AuthSession"; if (process.env.NEXT_RUNTIME === 'nodejs' && process.env.NODE_ENV !== 'production' && process.env.MSW_ENABLED !== 'false') { const {server} = require('@/mocks/http') server.listen() } const inter = Inter({subsets: ['latin']}) export const metadata: Metadata = { title: 'Create Next App', description: 'Generated by create next app', } type Props = { children: React.ReactNode, }; export default function RootLayout({children}: Props) { return ( <html lang="en"> <body className={inter.className}> <MSWProvider> <AuthSession> {children} </AuthSession> </MSWProvider> </body> </html> ) }
-
미해결Next + React Query로 SNS 서비스 만들기
fetch 캐싱과 revalidate 관련
안녕하세요 제로초님 fetch 캐싱과 revalidate 관련해서 궁금한 점이 있어 질문드립니다. await fetch('https://api.example.com/posts', { next: { revalidate: 60 }, });A가 /posts를 최초 요청합니다.→ API에서 데이터를 받아오고, 해당 데이터는 Next.js 서버 캐시에 저장이후 60초 동안은 다른 누구든지 이 캐시된 데이터를 그대로 받음그런데 60초가 지나기 전에 DB에서 게시글 1번의 제목이나 내용이 수정됨60초가 지나고 A가 다시 목록을 요청→ 이 시점은 revalidate 만료 시점 이후이므로 재검증 타이밍→ 하지만 A는 여전히 이전 캐시 데이터를 먼저 받고,→ A의 요청을 계기로 Next.js가 백그라운드에서 API를 다시 fetch하여 캐시를 갱신곧이어 B가 /posts를 요청하면→ B는 A 덕분에 갱신된 최신 데이터를 바로 받음 제가 이해한 것이 맞을까요? 만약 저런식으로 동작하면 상세 페이지와 데이터 불일치 문제가 발생할 수 있지 않을까 해서요 만약 상세 페이지 요청도 이렇게 작성되어 있다면await fetch('https://api.example.com/posts/1', { next: { revalidate: 60 }, });A는 목록 요청만 했고, 상세 페이지는 요청하지 않음B는 A 이후에 목록을 보고 → 최신 제목을 확인한 뒤,→ 게시글 1번의 상세 페이지를 클릭그런데 상세 페이지의 제목은 여전히 수정 전의 이전 제목으로 보임→ 목록과 상세 페이지 간에 데이터가 불일치할 수 있음정리하자면 제가 이해한 Next.js의 fetch + revalidate 캐시 동작이 맞는지 궁금하고위와 같은 목록-상세의 데이터 불일치 현상은 실제로 발생 가능한 문제인지 궁금합니다. 제가 실제로 테스트해봤을 때 위 시나리오대로 목록과 상세 페이지에서 서로 다른 제목이 보이는 걸 확인했습니다. 혹시 제가 잘못 이해하고 테스트한 부분이 있는 건지, 아니면 실제로도 발생할 수 있는 동작인지 궁금합니다.
-
미해결Next + React Query로 SNS 서비스 만들기
강의 듣는 방법
안녕하세요.강의를 어떤 방식으로 듣는 것이 가장 효율적인지 여쭤보고 싶습니다.처음 page.tsx를 만들 때는 하나하나 따라 만들며 진행했지만, 중간부터는 급하게 따라가기만 하다 보니 시간도 오래 걸리고, 오히려 비효율적이라는 생각이 들었습니다.또한 수업 자료의 GitHub를 보면 각 폴더 설명에 "따라치기 위해 보면 안 된다"고 안내되어 있어서, 제가 잘못된 방식으로 수강하고 있는 건 아닌지 고민이 됩니다.그리고 ch0~ch4 강의 이후의 코드를 올려주신 것은, 강의를 들으면서 이해가 안 되거나 따라가지 못한 부분이 있을 경우 해당 코드를 참고하거나 다운로드해서 사용해도 괜찮다는 의미일까요?또한 강의 초반에 GitHub에서 해당 폴더로 들어가 복사하고, 설명을 들으며 진도를 나가는 방식이라고 말씀하신 것을 보았는데, 그렇다면 굳이 모든 코드를 따라 치기보다는 전체 코드를 먼저 불러온 뒤 실행해두고, 강의를 들으며 흐름과 설명 위주로 이해하는 방식으로 수강해도 괜찮을지 궁금합니다.지금처럼 따라치며 수강하려다 보니 상대적으로 시간이 많이 소요되고, 비효율적일 수 있다는 생각이 들어 이렇게 문의드립니다.이에 대해 보다 효율적인 수강 방법에 대해 조언해주시면 감사하겠습니다.
-
미해결Next + React Query로 SNS 서비스 만들기
40강 로그인
안녕하세요! 40강 관련 질문입니다. 강의에서 로그인 하는 방식을 두 가지 알려주셨습니다. 서버액션 사용서버액션 미사용 서버액션 미사용해서 구현할 때 tanstack query 의 mutation 을 사용하는 방식도 좋지 않을까 생각을 하는데요, 로그인 버튼에 loading 처리를 하거나 등 의 이유로요! 근데 제로초님은 useState 만 쓰셨는데, 간단하게 보여주기 위해서 그렇게 하신걸까요? 로그인/회원가입에 tanstack query 를 사용하는 것이 추천하는 방식은 아닌걸까요?? 제가 강의 들으면서 개인프로젝트에 적용하고 있어서, 어떤 방식이 좋은지 고민이 돼서 여쭙니다!