묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨Next + React Query로 SNS 서비스 만들기
서버는 어떻게 socket을 받는건가요??
좋은 강의 잘 보고 있습니다!혹시 웹소켓을 사용하면서 서버쪽은 어떻게 코드가 구성되는지 알 수 있을까요??
-
미해결Next + React Query로 SNS 서비스 만들기
로딩 페이지, 에러 페이지 질문
React뿐만 아니라 NextJS에서도 <ErrorBoundary fallback={<Error/>}> <Suspense fallback={<Loading/>}> <Page /> </Suspense> </ErrorBoundary>이렇게 컴포넌트 계층 구조를 작성해야 한다는 것인가요? 아니면 그냥 error.tsx, loading.tsx파일만 만들면 알아서 적용이 된다는 것인가요?
-
해결됨Next + React Query로 SNS 서비스 만들기
msw 서버가 작동 안되요
window환경이고 회원가입을 하려고 해도 message가 넘어오지 않아 보니위 메세지도 콘솔에 뜨지않았습니다. Mock server자체가 연결이 안되는 것 같은데 뭐가 문제인지 잘 모르겠습니다. /mocks 폴더안에 파일들은 제로초님 깃헙에서 그대로 복붙하고 signup 관련 파일도 다 복붙했습니다./_lib/signup.ts 는 ts오류가나서 함수 이름만 넣었습니다."use server"; import { redirect } from "next/navigation"; const Submit = async (prevState: any, formData: FormData) => { if (!formData.get("id") || !(formData.get("id") as string)?.trim()) { return { message: "no_id" }; } if (!formData.get("name") || !(formData.get("name") as string)?.trim()) { return { message: "no_name" }; } if ( !formData.get("password") || !(formData.get("password") as string)?.trim() ) { return { message: "no_password" }; } if (!formData.get("image")) { return { message: "no_image" }; } let shouldRedirect = false; try { const response = await fetch( `${process.env.NEXT_PUBLIC_BASE_URL}/api/users`, { method: "post", body: formData, credentials: "include", }, ); console.log(response.status); if (response.status === 403) { return { message: "user_exists" }; } console.log(await response.json()); shouldRedirect = true; } catch (err) { console.error(err); return; } if (shouldRedirect) { redirect("/home"); // try/catch문 안에서 X } }; export default Submit; 아래는 제 package.json입니다. .env.localsubmit 눌렀을 때 네트워크
-
해결됨Next + React Query로 SNS 서비스 만들기
useInifiniteQuery queryKey 타입 지정 질문
검색 결과를 인피니트 스크롤로 바꾸던중에기존에 getSearchResult에서 queryKey 타입을QueryFunction을 이용해서 지정해주셨는데pageParam의 타입도 지정하는 방법이 따로 있을까요? 아니면 위와 같이 타입 지정을 해줘도 되는지 궁금합니다!
-
해결됨Next + React Query로 SNS 서비스 만들기
target으로 받아서 쓰는 이유는 뭔가요?
나중에 props로 받은 post를 target에 할당해서 사용하는 거로 바뀌던데 target에 담아서 사용하시는 이유가 궁금합니다.
-
미해결Next + React Query로 SNS 서비스 만들기
다크모드
@media (prefers-color-scheme: dark) { html { color-scheme: dark; } }다크모드 관련 css 수정하지 않았는데, 다크모드일 경우 색이 적용안되는 경우 이유를 알 수 있을까요?
-
해결됨Next + React Query로 SNS 서비스 만들기
SSR vs CSR
강의 영상 3분에 나온 SSR이 프론트 서버에 부담이 된다 라는 얘기가 잘 이해가 안가서 질문드립니다! 오히려 SSR은 프론트에서 모두 다운받아야 할 JS를 사전에 렌더링하고, query 코드를 읽지도 않기 때문에 더 부담이 안되지 않을까요...?? 또한 말씀하신 SEO 뿐만 아니라 suspense를 사용하거나 서버 액션을 통해 DB와 api 없이도 직접 통신할 수 있는 등의 장점이 있기에 자주 fetch를 해야 하는 작업이 아니라면 SSR의 장점이 더 많은게 아닌지 궁금합니다! CSR을 사용했을때의 장점은 fetch를 자주해야 하는 상황이 아니라면 어떤게 있는지 모르겠습니다.
-
미해결Next + React Query로 SNS 서비스 만들기
url을 통한 반응과 state를 이용한 반응 차이 관련 질문
수업을 진행하다가 그 당시에도 궁금즘이 생겨 개인적으로 알아봤던 부분인데, 확신이 안가서 강사님께 여쭈어봅니다. 수업 내용에서는 정확한 위치가 기억이 나지 않아서 다른 예시로 대체하겠습니다. 흰색 배경의 button group이 있고 각각의 button은 클릭할 시 url을 변경시킵니다.또한 현재 선택된 button은 색상이 칠해집니다. 이러한 상황에서 useState를 통해서 button의 state를 관리하고 있었고, button을 클릭했을때setState를 통해 선택하는 button을 변경함router을 통해 url 경로를 변경함이렇게 두가지 액션을 취했었습니다. 그 때 생겼던 궁금중은 어차피 url과 button은 mapping 할 수 있으니까, 버튼을 클릭하면 url만 변경시키고, url을 읽어서 button에 다시 값을 주면 기능적으로 똑같지 않나? 그러면 하나의 액션으로 기존의 두가지 액션을 대체할 수 있지 않나? 라고 생각했습니다. 그래서 조금 찾아보니까 url을 바꾸고 그 값을 통해 button의 상태 관리를 다시 하는건 즉각적인 반응이 아니고, 영상에서 봤던 것 처럼 url과 button state를 각각 바꾸는게 더 인터랙티브하다 라는 글을 읽었습니다. (신빙성이 있는 글은 아닙니다.) 실제로 이러한 이유 때문에 url만 바꾸고, 그 값을 받아와 button 값을 할당하는게 아니라, 두가지를 모두 동시에 바꾸는게 더 좋은 방법이 맞는건지 궁금합니다.
-
미해결Next + React Query로 SNS 서비스 만들기
nav 버튼들 분기에 관한 질문이 있습니다.
{segment === 'home' ? <> <svg width={26} viewBox="0 0 24 24" aria-hidden="true" className="r-18jsvk2 r-4qtqp9 r-yyyyoo r-lwhw9o r-dnmrzs r-bnwqim r-1plcrui r-lrvibr r-cnnz9e"> <g> <path d="M12 1.696L.622 8.807l1.06 1.696L3 9.679V19.5C3 20.881 4.119 22 5.5 22h13c1.381 0 2.5-1.119 2.5-2.5V9.679l1.318.824 1.06-1.696L12 1.696zM12 16.5c-1.933 0-3.5-1.567-3.5-3.5s1.567-3.5 3.5-3.5 3.5 1.567 3.5 3.5-1.567 3.5-3.5 3.5z"></path> </g> </svg> <div style={{fontWeight: 'bold'}}>홈</div> </> : <> <svg width={26} viewBox="0 0 24 24" aria-hidden="true" className="r-18jsvk2 r-4qtqp9 r-yyyyoo r-lwhw9o r-dnmrzs r-bnwqim r-1plcrui r-lrvibr r-cnnz9e"> <g> <path d="M12 9c-2.209 0-4 1.791-4 4s1.791 4 4 4 4-1.791 4-4-1.791-4-4-4zm0 6c-1.105 0-2-.895-2-2s.895-2 2-2 2 .895 2 2-.895 2-2 2zm0-13.304L.622 8.807l1.06 1.696L3 9.679V19.5C3 20.881 4.119 22 5.5 22h13c1.381 0 2.5-1.119 2.5-2.5V9.679l1.318.824 1.06-1.696L12 1.696zM19 19.5c0 .276-.224.5-.5.5h-13c-.276 0-.5-.224-.5-.5V8.429l7-4.375 7 4.375V19.5z"></path> </g> </svg> <div>홈</div> </> }강사님께서는 위 코드처럼 세그먼트에 따라 삼항연산자를 이용하여 아이콘이 들어있는 전체를 렌더링하셨는데요,style={{fontWeight: segment === 'home' ? 'bold' : 'initial'}}위 처럼 똑같이 삼항 연산자를 이용하되, style, svg path 등 필요한 부분만 유동적으로 변하도록 하지 않으신 특별한 이유가 있으신지 궁금합니다.
-
해결됨Next + React Query로 SNS 서비스 만들기
next/Image와 <img>의 사용하시는 기준이 있을까요?
뒤에서 수정이 되는지는 잘 모르겠지만 현재까지 강의에서는 양쪽 다 사용하시는 것 같습니다. 혹시 따로 구분하신다면 기준을 갖고 쓰시는지 궁금합니다.
-
해결됨Next + React Query로 SNS 서비스 만들기
dayjs 플러그인 질문있습니다.
dayjs를 사용하시기전에 dayjs.locale("ko"); dayjs.extend(relativeTime); 이렇게 쓰셧는데 dayjs를 매번 쓸때마다 컴포넌트에서 위코드가 들어가야하는지 궁금합니다.
-
미해결Next + React Query로 SNS 서비스 만들기
explore의 TrendSection에서 data를 useQuery가 아니라 getQueryData로 가져와서 사용해도 되나요?
(afterLogin)의 공통컴포넌트 TrendSection에서 fetch해온 데이터를 아래 코드처럼 explore의TrendSection에서 getQueryData로 가져와서 사용해도 되나요? 일단 잘 나오기는 하는데 제가 getQueryData를 잘 이해하고 사용하는건지 의문이 드네요... const queryClient = useQueryClient(); const data = queryClient.getQueryData(["trends"]);
-
해결됨Next + React Query로 SNS 서비스 만들기
SSR 적용이 안되어 있다면 어떤 부분을 체크해보면 좋을까요?
현재 Home 페이지를 확인해보면 작성된 게시글들이 아닌 Spinner가 돌고 있는것을 보아 SSR 적용이 되지 않은 것 같습니다. 유저 페이지의 경우에도 게시글들이 보이지 않아서 어떤 부분을 보고 수정해야할지 궁금합니다. 현재 Home 페이지와 [username]의 페이지에서 Hydrate 해주는 코드가 있으면 SSR 적용이 되는걸로 알고 있었는데 코드 부분에서 이상을 못느끼겠습니다ㅠㅠ// src\app\(afterLogin)\home\_component\TabDeciderSuspense.tsx import TabDecider from "@/app/(afterLogin)/home/_component/TabDecider"; import { dehydrate, HydrationBoundary, QueryClient, } from "@tanstack/react-query"; import { getPostRecommends } from "@/app/(afterLogin)/home/_lib/getPostRecommends"; export default async function TabDeciderSuspense() { const queryClient = new QueryClient(); await queryClient.prefetchInfiniteQuery({ queryKey: ["posts", "recommends"], queryFn: getPostRecommends, initialPageParam: 0, }); const dehydratedState = dehydrate(queryClient); return ( <HydrationBoundary state={dehydratedState}> <TabDecider /> </HydrationBoundary> ); } // src\app\(afterLogin)\[username]\page.tsx import style from "./profile.module.css"; import { dehydrate, HydrationBoundary, QueryClient, } from "@tanstack/react-query"; import UserPosts from "@/app/(afterLogin)/[username]/_component/UserPosts"; import UserInfo from "@/app/(afterLogin)/[username]/_component/UserInfo"; import { getUserPosts } from "@/app/(afterLogin)/[username]/_lib/getUserPosts"; import { getUserServer } from "@/app/(afterLogin)/[username]/_lib/getUserServer"; import { auth } from "@/auth"; import { User } from "@/model/User"; type Props = { params: { username: string }; }; export async function generateMetadata({ params }: Props) { const user: User = await getUserServer({ queryKey: ["users", params.username], }); return { title: `${user.nickname} (${user.id}) / Z`, description: `${user.nickname} (${user.id}) 프로필`, }; } export default async function Profile({ params }: Props) { const { username } = params; const session = await auth(); const queryClient = new QueryClient(); await queryClient.prefetchQuery({ queryKey: ["users", username], queryFn: getUserServer, }); await queryClient.prefetchQuery({ queryKey: ["posts", "users", username], queryFn: getUserPosts, }); const dehydratedState = dehydrate(queryClient); return ( <main className={style.main}> <HydrationBoundary state={dehydratedState}> <UserInfo username={username} session={session} /> <div> <UserPosts username={username} /> </div> </HydrationBoundary> </main> ); }
-
미해결Next + React Query로 SNS 서비스 만들기
PhotoModal 페이지 인터셉팅 라우트 질문
/compose/tweet 이나 /i/flow/login 에서 패러렐 라우트와 인터셉팅 라우트를 사용했을 때는 @modal 안에서 (.)compose 혹은 (.)i 로 작성했는데 이번 PhotoModal 페이지는 @modal 안에서 (.)[username]이 아닌 그냥 [username]으로 폴더 구조를 짜셨더라구요. 이러면 인터셉팅이 이루어지지 않는 것 아닌가요? 추가로 children으로 들어가는 /[username]/status/[id]/photo/[photoId]에 있는 page.tsx에서 강의자료에는 return ( <Home /> ); 이렇게 하고 있는데새로고침을 해도 제대로 나오려면 이렇게 하는 것이 맞는지 궁금합니다.return ( <> <Home /> <PhotoModalPage /> </> );
-
미해결Next + React Query로 SNS 서비스 만들기
인터셉팅 했을 때 children에 들어가는 것 원리를 모르겠습니다.
인터셉터 전/modal : /@modal/default.tsxchildren : /page.tsx/i/flow/login (링크 클릭)modal : /@modal/i/flow/login/page.tsxchildren : /i/flow/login/page.tsx/i/flow/login (직접 접속)modal : /@modal/i/flow/login/page.tsxchildren : /i/flow/login/page.tsx 인터셉터 후/modal : /@modal/default.tsxchildren : /page.tsx/i/flow/login (링크 클릭)modal : /@modal/(.)i/flow/login/page.tsxchildren : /page.tsx/i/flow/login (직접 접속)modal : /@modal/default.tsxchildren : /i/flow/login/page.tsx 인터셉터와 패러렐 각각은 이해를 했습니다. 패러렐은 위에 적어놓았고,인터셉터만 적용했다면 /i/flow/login (링크 클릭) 했을 때 {children}에 /(.)i/flow/login/page.tsx가 들어갔을테고,/i/flow/login (직접 접속) 했을 때 /i/flow/login/page.tsx가 들어갔겠죠. /i/flow/login (링크 클릭) 했을 때 인터셉팅 동시에 패러렐이기 때문에 {modal}에 /@modal/(.)i/flow/login/page.tsx이 들어갑니다.그런데.. {children}에는 왜 /page.tsx가 들어가는지 모르겠습니다. 반대로, "그렇다면 왜 /page.tsx가 들어가면 안 되는데?" 이 질문에도 대답을 못하겠습니다 ㅠㅠ;그리고 /i/flow/login (직접 접속) 했을 때도 {modal}이 왜 /@modal/default.tsx인지 모르겠습니다.
-
해결됨Next + React Query로 SNS 서비스 만들기
인터셉팅 라우터로 구현된 모달 닫을 때 질문있습니다.
인터셉팅 라우터가 열린채로 router.push()를 했을때 모달이 열린채로 뒤에만 이동되는데 router.back() 말고 닫을 수 있는 방법이 있을까요?
-
해결됨Next + React Query로 SNS 서비스 만들기
참조 끊어내기 관련 질문입니다.
const shallow = {...value}; // 참조 끊어내기 value.pages = [...value.pages] value.pages[pageIndex] = [...value.pages[pageIndex]];참조를 끊어내어 react query의 state를 update 해주는건 이해 했습니다. 하지만 강의에서는 value.pages = {...value.pages} 를 이용하는데, pages를 객체로 덮어씌워 원래 배열을 바꾸는 이유가 따로 있을까요?
-
미해결Next + React Query로 SNS 서비스 만들기
auth signin 함수에 대해
조금 혼란스러운 부분이 있습니다. auth.ts를 보면 export const {}=NextAuth를 통해 signIn함수를 외부로 보낼 수 있게 만드셨는데요. 다른 페이지에서 signIn을 사용하실때 LoginModal에서는 next-auth/react에서 호출한 signIn을, _lib의 signup에서는 @/auth의 signIn을 사용하셨는데, 어떤걸 사용해야 하는거고 무슨 차이인지 모르겠습니다.
-
미해결Next + React Query로 SNS 서비스 만들기
서버사이드 세션을 auth()로 가져와서 session값을 변경하는 방법 문의
클라이언트컴포넌트에서는 const {data:session, update} = useSession(); 로 세션값을 가져올때 update 함수도 함께 가져와서 update()하고 next-auth의 callback함수에서 세션값을 업데이트해주면 세션값을 변경할 수 있을것입니다. 문제는 서버용으로 const session = await auth(); 로 값을 가져오면 세션에 값을 변경을 할 수 있을까요?
-
미해결Next + React Query로 SNS 서비스 만들기
build 에러 Error occurred prerendering page
Error occurred prerendering page "/newpost". Read more: https://nextjs.org/docs/messages/prerender-errorReferenceError: document is not definedat 46593 (/Users/gyeongdeokpark/Documents/01.GitHub/codeblog/.next/server/app/newpost/page.js:2:59980)at __webpack_require__ (/Users/gyeongdeokpark/Documents/01.GitHub/codeblog/.next/server/webpack-runtime.js:1:146)at F (/Users/gyeongdeokpark/Documents/01.GitHub/codeblog/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:36:6049)at /Users/gyeongdeokpark/Documents/01.GitHub/codeblog/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:36:8464at W._fromJSON (/Users/gyeongdeokpark/Documents/01.GitHub/codeblog/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:36:8902)at JSON.parse (<anonymous>)at L (/Users/gyeongdeokpark/Documents/01.GitHub/codeblog/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:36:5770)at t (/Users/gyeongdeokpark/Documents/01.GitHub/codeblog/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:36:12155)✓ Generating static pages (5/5)> Export encountered errors on following paths:/newpost/page: /newpost npm run build시에 발생하는 에러입니다. 각종 사이트에서는 14버전에서 에러가 발생하고 있다고 하는 글 들만 있고 해결방법을 찾지 못했습니다..gpt에서는 클라이언트 사이드에서 실행되어야 하는 코드가 서버 사이드에서 실행되서 그렇다고 하는데잘해결이 안되고 있습니다. npm run dev시에는 에러없이 잘 실행됩니다."use client"; import React, { ChangeEventHandler, useState } from "react"; import LexicalEditor from "@/app/newpost/LexicalEditor"; function Page({ props }: any) { const [title, setTitle] = useState(""); const [content, setContent] = useState(""); const onChangeTitle: ChangeEventHandler<HTMLInputElement> = (e) => { setTitle(e.target.value); }; const onSubmit = (e: any) => { e.preventDefault(); console.log("제목 : ", title); console.log("내용 : ", content); }; return ( <form className="postForm" onSubmit={onSubmit}> <div className="postForm__titleInputSection"> <input className="postForm__titleInput" type="text" name="title" value={title} onChange={onChangeTitle} placeholder={"제목을 입력하세요."} /> </div> <div className="postForm__editorWrapper"> <LexicalEditor /> </div> <button>작성하기</button> </form> ); } export default Page; 깃허브 링크 입니다. https://github.com/littleduck1219/codeblog/blob/main/src/app/newpost/page.tsx