inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

172만명의 커뮤니티!! 함께 토론해봐요.

handlers.ts에서 회원가입쪽 handler를 짤때의 질문입니다.

미해결

Next + React Query로 SNS 서비스 만들기

http.post('/api/users', async ({ request }) => { console.log('회원가입'); // return HttpResponse.text(JSON.stringify('user_exists'), { // status: 403, // }) return HttpResponse.text(JSON.stringify('ok'), { headers: { 'Set-Cookie': 'connect.sid=msw-cookie; HttpOnly;Path=/;Max-Age=0' } }) }), 현재 위 코드가 제로초님의 회원가입 코드인데 로그아웃을 할때 세션을 만료하기위해서 Max-Age=0을 넣는것은 이해가 되지만 왜 굳이 회원가입을 할때도 Max-Age=0을 붙이신건가요? 회원가입시 쿠키가 왜 필요한지와 필요하다고하더라도 왜 굳이 바로 Max-Age=0을 추가해서 바로 만료시켜버리는지가 궁금합니다!

  • react
  • next.js
  • react-query
  • next-auth
  • msw
김창훈 댓글 1 좋아요 0 조회수 261

강의자료 부탁드립니다!

해결됨

팀 개발을 위한 Git, GitHub 입문

강의자료 부탁드립니다! aireddy@naver.com

  • git
  • github
  • 버전관리시스템
lee_wonhee 댓글 2 좋아요 0 조회수 253

react-query의 useSuspense.. 사용 시 클라이언트에서 suspense가 동작을 하지 않습니다.

미해결

Next + React Query로 SNS 서비스 만들기

안녕하세요. 강사님 예제를 보고 하던 중 suspense 가 동작하지 않아 질문드립니다. 처음 예시로 알려주신 react-query의 isPending 을 사용한 로딩처리는 잘 동작하지만 마지막에 알려주신 useSuspense( useSuspenseInfiniteQuery, useSuspenseQuery )들을 사용하는 경우 동작하지 않네요.. * 팔로우 중 을 선택해도 suspense에 설정한 로딩 컴포넌트가 나오지 않고 딜레이된 시간(5초) 후 데이터가 보여집니다. 로딩 컴포넌트도 회전하지 않고 멈춰있습니다. 어떤부분을 봐야할까요?ㅠㅠ 반대로 이런 증상을 경험하니 이전 데이터가 먼저 보여진 후 5초 뒤에 최신 데이터로 보여지므로 사용자가 잘 못된 데이터를 표시 할 수 있다는걸 배울 수 있었습니다. 😎 소스코드 const HomePage = async () => { return ( <HomeContextProvider> <HomeTopTab /> <WriteForm /> <Suspense fallback={<Loader />}> <TabDividerSuspense /> </Suspense> </HomeContextProvider> ); }; const TabDividerSuspense = async () => { const queryClient = new QueryClient(); await queryClient.prefetchInfiniteQuery({ queryKey: ["tweet", "recommends"], queryFn: getPostRecommends, initialPageParam: 0, }); const dehydratedState = dehydrate(queryClient); return ( <HydrationBoundary state={dehydratedState}> <TabDivider /> </HydrationBoundary> ); }; const TabDivider = () => { const { tab } = useContext(HomeContext); return tab === "recommended" ? <TweetList /> : <FollowingList />; }; const TweetList = () => { const { ref, inView } = useInView(); const { data, fetchNextPage, hasNextPage, isFetching, isPending } = useSuspenseInfiniteQuery< Post[], object, InfiniteData<Post[]>, [string, string], number >({ queryKey: ["tweet", "recommends"], queryFn: getPostRecommends, initialPageParam: 0, getNextPageParam: (lastPage) => lastPage.at(-1)?.postId, }); useEffect(() => { if (inView) { !isFetching && hasNextPage && fetchNextPage(); } }, [fetchNextPage, hasNextPage, inView, isFetching]); const tweets = useMemo(() => { if (data) { return data.pages.flat(); } }, [data]); return ( <> {tweets?.map((tweet) => ( <Tweet post={tweet} key={tweet.postId} /> ))} {isPending && <Loader />} <div ref={ref} /> </> ); }; 추가 질문 빌드 후 네트워크 탭에서 home 을 확인해보면 post 글 들이 모두 html로 변환되어 내려 오고 있습니다! (dev에서는 템플릿?으로 표현되더라고요) 저는 html이 아닌 데이터 형태로 내려와 useQuery로 해당 키로 접근해서 그냥 데이터를 가져올 줄 알았는데..그게 아닌가 보네요. 혹시 좀 더 자세히 설명 좀 부탁드려도 될까요?ㅠ 그리고 home 의 미리보기 탭에서는 post글들이 아닌 로딩 컴포넌트가 보입니다. (위의 사진에 응답 탭에서는 post글 들이 존재하고요) 로딩 컴포넌트가 보이는 이유는 하이드레이션이 처리되기 전이라 그런게 맞나요? 지금 자료를 다시 찾으려니 못 찾고 있는데.. suspense를 사용할 경우 완성된 화면이 아닌 로딩화면을 먼저 내려주므로 seo에는 나쁠 수 있다 라는 글을 본적이 있던 것 같은데..맞을까요? *SEO 관련해서 추가로 궁금한건 강의가 따로 있다고 영상에서 말씀하셔서 거기까지 보고 필요할 경우 질문 한번 더 드리겠습니다. 👍

  • react
  • next.js
  • react-query
홍홍 댓글 2 좋아요 0 조회수 1147

브렌치와 머지 질문입니다.

미해결

게임처럼 공부하는 git 던전

오른쪽이 제화면이고 왼쪽이 선생님화면입니다. 현재상황: 기본명령어 commit, push, pull 1강부터 들으면서 example01 브렌치를 만들고 난후 pull하고 pr을 안한상태로 2강으로 넘어와 mable과 tree브렌치를 만들었습니다. 그리고 marge를 example01 into main을 눌렀더니 위와 같이 화면이 동그라미가 안생겼는데요. 머쥐를 취소 하기 위해 위와 같은 명령어를 썼는데도 안되서요. 혹시 선생님 화면처럼 동그라미를 만들기 위해서 어떻게 해야 하나요? mable브렌치로 퀘스트 실행했는데 현재 깃을 보면 아무것도 안나와서요. 깃주소는 : https://github.com/raikeni/test44 입니다.

  • git
  • github
아메 댓글 1 좋아요 0 조회수 216

변수, useState 부분 질문있습니다.

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

안녕하세요 수업 너무 잘 듣고 있습니다. 수업을 듣다 궁금한점이 생겼는데 제가 인강을 보면서 변수 let, const와, 리액트에서 useState부분을 보고 이해는 갔지만 제가 막상 혼자 코드를 친다고 했을때 let, const와 useState를 언제 작성을 하면 되는지 잘 모르겠더라구요. 혼자 코드를 작성을 한다고 할때 변수와 useState를 언제 작성을 하면된다라고 이해를 하면 쉽게 이해할수있을까요?

  • react
  • node.js
  • seo
  • graphql
  • next.js
부드러운 족제비 댓글 1 좋아요 0 조회수 148

link태그의 prefetching 질문

미해결

Next + React Query로 SNS 서비스 만들기

안녕하세요 선생님 상세페이지에서 홈으로 이동할때 로딩화면에 관련해서 Link태그의 prefetching 질문있습니다. 아래와 같이 suspense를 적용했을때 app/(afterLoging)/home/page.tsx import style from './home.module.scss' import Tab from "@/app/(afterLogin)/home/_component/Tab"; import TabProvider from "@/app/(afterLogin)/home/_component/TabProvider"; import PostForm from "@/app/(afterLogin)/home/_component/PostForm"; import TabDeciderSuspense from '@/app/(afterLogin)/home//_component/TabDeciderSuspense'; import { Suspense } from 'react'; import Loading from './loading'; import { auth } from '@/auth'; export default async function Home() { const session = await auth(); return ( <main className={style.main}> <TabProvider> <Tab /> <PostForm me={session} /> {/* suspense는 서버컴포넌트여야만 한다. */} {/* suspense는 부모컴포넌트여야지 자식(아래)있는 컴포넌트 감지할 수 있다. */} <Suspense fallback={<Loading />}> <TabDeciderSuspense /> </Suspense> </TabProvider> </main> ); } next.js 문서를 보면 link태그가 있는 경우, 화면에 들어왔을때 static한 부분은 prefetch하고, 데이터 호출이 필요한 경우는 loading.tsx까지 호출해준다고 되어있더라구요. 그래서 제가 기대한 것은 상세페이지에서, 홈의 Link태그가 화면에 들어오기 대문에, 홈으로 이동했을때 첫번째 이미지가 아닌, 두번째 이미지처럼 로딩이 되어야할 것 같은데 첫번째 이미지 처럼 되더라구요. (이동한것도 30초 이내였습니다) 혹시 제가 잘못이해한건지 알려주시면 감사합니다. 유저 상세페이지에서 홈으로 이동할때 suspense적용후 새로고침하거나 팔로우중 클릭시

  • react
  • next.js
  • react-query
  • next-auth
  • msw
챠챠_ 댓글 1 좋아요 0 조회수 241

찜하기하고 해당글 상세페이지 이동시 찜 정보제대로 안내려오는 현상

미해결

Next + React Query로 SNS 서비스 만들기

안녕하세요 선생님 홈에서 찜했다, 안했다 잘 작동하고 상세페이지로 이동하면 찜하기 데이터가 제대로 내려오지 않는 부분을 확인했습니다. 호출은 아래와 같이 하고있습니다. /src/app/(afterLogin)/[username]/status/[id]/page.tsx import BackButton from "@/app/(afterLogin)/_component/BackButton"; import style from './singlePost.module.scss'; import Post from "@/app/(afterLogin)/_component/Post"; import CommentForm from "@/app/(afterLogin)/[username]/status/[id]/_component/CommentForm"; import SinglePost from '@/app/(afterLogin)/[username]/status/[id]/_component/SinglePost'; import Comments from '@/app/(afterLogin)/[username]/status/[id]/_component/Comments'; import { HydrationBoundary, QueryClient, dehydrate } from '@tanstack/react-query'; import { getSinglePost } from '@/app/(afterLogin)/[username]/status/[id]/_lib/getSinglePost'; import { getComments } from '@/app/(afterLogin)/[username]/status/[id]/_lib/getComments'; type Props = { params: { id: string} } export default async function Pasge({ params }: Props) { console.log('----------------------------- single post params', params); const { id } = params; const queryClient = new QueryClient(); await queryClient.prefetchQuery({ queryKey: ['posts', id], queryFn: getSinglePost }); await queryClient.prefetchQuery({ queryKey: ['posts', id, 'comments'], queryFn: getComments }); const dehydratedState = dehydrate(queryClient); return ( <div className={style.main}> <HydrationBoundary state={dehydratedState}> <div className={style.header}> <BackButton/> <h3 className={style.headerTitle}>게시하기</h3> </div> <SinglePost id={id} /> <CommentForm id={id} /> <div> <Comments id={id} /> </div> </HydrationBoundary> </div> ) } /src/app/(afterLogin)/[username]/status/[id]/_component/SinglePost.tsx 'use client'; import { Post as IPost } from '@/models/Post' import { useQuery } from '@tanstack/react-query' import { getSinglePost } from '@/app/(afterLogin)/[username]/status/[id]/_lib/getSinglePost'; import Post from '@/app/(afterLogin)/_component/Post'; export default function SinglePost({id, noImage}: {id: string, noImage?: boolean}) { const { data: post, error } = useQuery<IPost, Object, IPost, [_1: string, _2: string]>({ queryKey: ['posts', id], queryFn: getSinglePost, staleTime: 60 * 1000, gcTime: 300 * 100, }); console.log(post, '--------------------------single post'); if (error) { return ( <div style={{ height: 100, alignItems: 'center', fontSize: 31, fontWeight: 'bold', display: 'flex', justifyContent: 'center' }}>게시글을 찾을 수 없습니다.</div> ) } if (!post) { return null; } return <Post post={post} key={post.postId} noImage={noImage} /> } 찜하기 코드 export default function ActionButtons({ white, post }: Props) { const queryClient = useQueryClient(); const { data: session } = useSession(); const commented = !!post.Comments?.find(d => d.userId === session?.user?.email); const reposted = !!post.Reposts?.find(d => d.userId === session?.user?.email); const liked = !!post.Hearts?.find(d => d.userId === session?.user?.email); const { postId } = post; const heart = useMutation({ mutationFn: () => { return fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/posts/${postId}/heart`, { method: 'post', credentials: 'include', }) }, onMutate() { const queryCache = queryClient.getQueryCache(); const queryKeys = queryCache.getAll().map(cache => cache.queryKey); console.log('queryKey', queryKeys); queryKeys.forEach((queryKey) => { if (queryKey[0] === 'posts') { const value: Post | InfiniteData<Post[]> | undefined = queryClient.getQueryData(queryKey); if (value && 'pages' in value) { const obj = value.pages.flat().find(d => d.postId === postId); if (obj) { // 존재는 하는지? const pageIndex = value.pages.findIndex(page => page.includes(obj)); const index = value.pages[pageIndex].findIndex(d => d.postId === postId); const shallow = produce(value, draft => { draft.pages[pageIndex][index].Hearts = [{ userId: session?.user?.email as string }]; draft.pages[pageIndex][index]._count.Hearts += 1; }) queryClient.setQueryData(queryKey, shallow); } } else if (value) { // 싱글 포스트인 경우 if (value.postId === postId) { const shallow = { ...value, Hearts: [...value.Hearts, { userId: session?.user?.email as string }], _count: { ...value._count, Hearts: value._count.Hearts + 1, } } queryClient.setQueryData(queryKey, shallow); } } } }) }, onError() { }, onSettled() { } }); 다른 찜하기 질문에서 키를가지고 호출하지 않해서라고 하신걸 봤었는데, 위와 같은 경우에는 클라이언트 서버에서 쿼리키를 가지고 호출했는데 데이터가 잘 안내려오는 것을 확인했습니다. 찜을 눌렀을때 찜을 누르고 해당글 상세로 이동했을때 이러한 경우에는 찜하기를 누르고 추가적인 작업이 필요한지 궁금합니다. 예를들면 찜하기를 누르고 해당 쿼리키의 데이터를 호출해야한다는지... 혹은 제가 잘못호출한것이라면 알려주시면 감사하겠습니다.

  • react
  • next.js
  • react-query
  • next-auth
  • msw
챠챠_ 댓글 1 좋아요 0 조회수 210

No API key found in request

해결됨

Supabase, Next 풀 스택 시작하기 (feat. 슈파베이스 OAuth, nextjs 14)

강의를 보고 같이 프로젝트도 만들어봤는데 문제가 생겨 글을 작성합니다. response 값을 확인하려고 네트워크 탭을 확인하니 프리플라이트가 같이 생성되고 클릭할 시 아래와 같은 메시지가 나옵니다. {"message":"No API key found in request","hint":"No apikey request header or url param was found."} 혹시 이 문제를 해결할 수 있는 방법을 알고 계신가요? 처음부터 supabase 설정을 다시 해야될까요?

  • react
  • 클론코딩
  • next.js
  • supabase
전지훈 댓글 1 좋아요 1 조회수 655

프로필 부분 getUser.ts Error가 반환되지 않는 이유를 모르겠습니다.

미해결

Next + React Query로 SNS 서비스 만들기

import { QueryFunction } from "@tanstack/react-query"; import { User } from "@/model/User"; const getUser: QueryFunction<User, [string, string]> = async ({ queryKey }) => { const [_1, username] = queryKey; const res = await fetch(`http://localhost:9090/api/users/${username}`, { next: { tags: ["users", username], }, cache: "no-store", }); console.log("res.ok : ", res.ok); if (!res.ok) { throw new Error("해당 유저 정보를 불러오지 못 했습니다."); } return res.json(); }; export default getUser; mocks>handler.ts에 없는 username을 url에 입력해도 res.ok로 떠서 if문을 그냥 통과해버립니다. 혹시 제가 놓치는 부분이 있는걸까요?

  • react
  • next.js
  • react-query
  • next-auth
  • msw
hwuiinn 댓글 1 좋아요 0 조회수 194

다른 팀원이 최신화시킨 원격 dev 브랜치를 가져올 때...

미해결

팀원들과 토이프로젝트를 하다가 궁금한 git pull 과 관련하여 궁금증이 생겨서 질문드립니다... github에 원격 master 브랜치로부터 원격 dev 브랜치를 만들고 거기서 파생된 feature 작업브랜치에서 다시 개인 이름을 넣어 개인 작업 브랜치를 통해 로컬에서 작업했는데요. 이 때, 다른 팀원이 작업한 내용을 dev에 merge 했고 그 최신 내용을 제 로컬 작업브랜치에 추가로 가져오고 싶은데 이럴 때 어떻게 하면 좋을까요...? 먼저 로컬 dev 브랜치로 체크아웃을 하고 git pull origin dev 명령어를 통해 로컬 dev 브랜치를 최신화시켰습니다. 그 다음에 개인 로컬 작업 브랜치로 다시 체크아웃하고 git merge dev 를 통해 최신화된 로컬 dev 브랜치를 작업 브랜치에 병합시켰는데요. 커밋 해야할 내역을 보니 이전에 다른 팀원들이 원격에서 최신화한 내용들이 변경사항으로 들어가있더라구요... 그래서 그 부분까지 커밋하게되면 그 분들이 작업한 부분을 제 커밋메세지로 덮어쓸거같아서 걱정입니다.. 제가 어느 부분에서 잘못 진행한걸까요...?

  • git
  • github
맥스 댓글 1 좋아요 0 조회수 328

prefetchQuery 관련 질문

미해결

Next + React Query로 SNS 서비스 만들기

prefetchQuery 서버컴포넌트에서 데이터를 한번 불러오면, 정상적으로 불러왔는지 확인할 수 있나요?? 서버 컴포넌트에서 prefetchQuery한 다음에 클라이언트컴포넌트에서 useQuery로 불러오게 되면(queryKey 동일) 이미 데이터가 저장 되어 있는거로 알고 있는데, console.log를 찍어보게 되면, undefined가 뜬 다음에 데이터가 호출 됩니다. prefetchQuery가 정상적으로 동작 안하는게 아닌가 싶습니다. export default function TestClient() { const { data } = useQuery({ queryKey: ['typeData'], queryFn: getTypeData, }); console.log(typeData); ... export default async function TestServer() { const queryClient = new QueryClient(); await queryClient.prefetchQuery({ queryKey: ['typeData'], queryFn: getTypeData }); const dehydratedState = dehydrate(queryClient); return ( <> <HydrationBoundary state={dehydratedState}> <TestClient /> </HydrationBoundary> </> ); }

  • react
  • next.js
  • react-query
  • next-auth
  • msw
oct.wanga 댓글 2 좋아요 0 조회수 281

리액트 설치에 대해 궁금한 점이 있습니다.

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

현재 리액트부분을 시작했는데 리액트를 설치할때 yarn add next@12.1.0 react@17.0.2 react-dom@17.0.2 --exact 이러한 명령어를 사용하는데 이렇게 설치하고 나니 제가 알고있는 폴더들이나 내용이 좀 다르더라구요. 제가 알고있는 건 npx create-react-app ./ 이러한 명령어로 리액트를 설치했는데 이거와 전혀 다른 명령어 인가요?

  • react
  • node.js
  • seo
  • graphql
  • next.js
부드러운 족제비 댓글 2 좋아요 0 조회수 262

yarn 설치가 되지않습니다.

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

node.js와 npm은 --version을 이용하니 버전이 나오는데 yarn은 버전이 나오지 않아 npm install -g yarn 이라는 명령어를 하니 이미지처럼 에러가 나옵니다.

  • react
  • node.js
  • seo
  • graphql
  • next.js
부드러운 족제비 댓글 2 좋아요 0 조회수 595

인터셉팅 라우터가 signup에는 적용이 안되는 문제

해결됨

Next + React Query로 SNS 서비스 만들기

login은 인터셉팅 라우터가 잘 되는데, signup은 (.)i로 인터셉팅이 안되고 버튼 클릭을 하면 그냥 i/flow/signup/page.tsx로만 보여지는 문제가 있습니다. 왜 signup은 인터셉팅 라우터가 작동이 안되는 것일까요?? 경로는 이렇게 잘 설정되어있고 안에 파일 내용은 아래와 같습니다. 아래는 @modal/(.)i/flow/signup/page.tsx 아래는 i/flow/signup/page.tsx 홈 버튼 링크는 아래와 같이 되어있습니다. 혹시 제가 빠뜨린 무엇이 있을까요?

  • react
  • next.js
  • react-query
  • next-auth
  • msw
이온 댓글 1 좋아요 0 조회수 344

섹션11 eslint 설치

해결됨

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

eslint 설치 시 3개 중에 마지막 3번째를 선택하라고 하는데 저는 선택지가 2개만 나옴니다. 2번째를 선택해서 설치해도 되나요?

  • react
  • node.js
  • seo
  • graphql
  • next.js
베이직 댓글 2 좋아요 0 조회수 461

http://localhost:3000/api/auth/session 500에러

미해결

Next + React Query로 SNS 서비스 만들기

안녕하세요 선생님 로컬에서 locallhost:3000/api/auth를 호출하면 500에러가 발생합니다. * 참고: 1. useSession()은 모두 클라이언트 컴포넌트에만 적용했습니다. 2. 원인을 찾아보다가 예전 선생님 답변해주신 서버 컴포넌트에서 세션props로 받아스라고 하신거 참고해서 그렇게 수정해도 동일하게 발생합니다. 3. 비슷한 질문에 쿠키랑 다 없앤뒤 잘됐다는것도 보고 다제거해봤지만 동일하게 발생했습니다. 4. .next, node_module 다 제거후 새로 깔거나, 빌드를 새로 하거나 테스트도 해보았습니다. 5. 브라우저 껐다키고, 컴퓨터 재부팅도 해보았습니다. 6. 선생님의 깃코드를 가져다 쓰기도 해보았습니다. 빌드 한후에 npm run start로 했을땐 정상적으로 나오는데 로컬에서만 발생합니다. /src/auth.ts import NextAuth from "next-auth" import Credentials from "next-auth/providers/credentials" export const { handlers, signIn, signOut, auth } = NextAuth({ pages: { signIn: '/login', newUser: '/signup', }, providers: [ Credentials({ credentials: { id: {}, password: {}, }, authorize: async (credentials) => { try { const authResponse = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/login`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(credentials), }) console.log(authResponse.ok, '-----------------------------authResponse.ok'); if (!authResponse.ok) { return null; } let user = await authResponse.json(); console.log(user, '--------------------------------'); return { ...user, email: user.id, name: user.nickname, image: user.image, } } catch (err) { console.error('로그인 에러', err); } }, }), ], }) .env AUTH_SECRET=WKFOJhbw7gZOYXumT66CwwKtDZ9YsalV8qMRx134Uc8= AUTH_TRUST_HOST=http://localhost:3000 .env.local NEXT_PUBLIC_API_MOCKING=enabled NEXT_PUBLIC_MODE=local NEXT_PUBLIC_BASE_URL=http://localhost:9090 NEXTAUTH_URL=http://localhost:3000 /src/app/layout.tsx import type { Metadata, Viewport } from "next"; import { Inter } from "next/font/google"; import "./globals.css"; import { MSWComponent } from './_component/MSWComponent'; import AuthSession from './_component/AuthSession'; const inter = Inter({ subsets: ["latin"] }); export const metadata: Metadata = { title: { template: '%s | MBTI', default: 'MBTI가 어떻게 되세요?', }, description: "MBTI로 찾는 내 연인", }; export const viewport: Viewport = { width: 'device-width', initialScale: 1, maximumScale: 1, userScalable: false, // Also supported by less commonly used // interactiveWidget: 'resizes-visual', } export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return ( <html lang="en"> <body className={`${inter.className} antialiased`}> <MSWComponent /> <AuthSession> {children} </AuthSession> </body> </html> ); } /src/app/_component 'use client'; import { SessionProvider } from 'next-auth/react'; import { ReactNode } from 'react'; export default function AuthSession({children}: {children: ReactNode}) { return ( <SessionProvider>{children}</SessionProvider> ) } /src/app/api/auth/[...nextauth]/route.ts import { handlers } from "@/auth" // Referring to the auth.ts we just created export const { GET, POST } = handlers; 폴더구조 📦src ┣ 📂app ┃ ┣ 📂(afterLogin) ┃ ┃ ┣ 📂(home) ┃ ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┃ ┣ 📜mbtiCarousel.module.css ┃ ┃ ┃ ┃ ┣ 📜MbtiCarousel.tsx ┃ ┃ ┃ ┃ ┗ 📜UserCardList.tsx ┃ ┃ ┃ ┗ 📂_lib ┃ ┃ ┃ ┃ ┗ 📜getUserAll.ts ┃ ┃ ┣ 📂@modal ┃ ┃ ┃ ┣ 📂(.)promise ┃ ┃ ┃ ┃ ┗ 📂form ┃ ┃ ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┃ ┣ 📂[userId] ┃ ┃ ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┃ ┃ ┣ 📜UserDetailContent.tsx ┃ ┃ ┃ ┃ ┃ ┣ 📜UserDetailPromise.tsx ┃ ┃ ┃ ┃ ┃ ┣ 📜UserDetailTop.tsx ┃ ┃ ┃ ┃ ┃ ┣ 📜UserInfo.tsx ┃ ┃ ┃ ┃ ┃ ┗ 📜UsrCarousel.tsx ┃ ┃ ┃ ┃ ┣ 📂_lib ┃ ┃ ┃ ┃ ┃ ┣ 📜getAUser.ts ┃ ┃ ┃ ┃ ┃ ┗ 📜getUserPromise.ts ┃ ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┃ ┗ 📜default.tsx ┃ ┃ ┣ 📂like ┃ ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┃ ┣ 📜LikeCard.tsx ┃ ┃ ┃ ┃ ┣ 📜LikeTabProvider.tsx ┃ ┃ ┃ ┃ ┣ 📜Tab.tsx ┃ ┃ ┃ ┃ ┣ 📜TabDecider.tsx ┃ ┃ ┃ ┃ ┣ 📜UserILike.tsx ┃ ┃ ┃ ┃ ┗ 📜UserLikeMe.tsx ┃ ┃ ┃ ┣ 📂_lib ┃ ┃ ┃ ┃ ┣ 📜getUserILike.ts ┃ ┃ ┃ ┃ ┗ 📜getUserLikeMe.ts ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂messages ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂profile ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂promise ┃ ┃ ┃ ┣ 📂form ┃ ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┃ ┣ 📜PromiseCard.tsx ┃ ┃ ┃ ┃ ┣ 📜PromiseCardDropdown.tsx ┃ ┃ ┃ ┃ ┣ 📜PromiseCardLink.tsx ┃ ┃ ┃ ┃ ┣ 📜PromiseFormButton.tsx ┃ ┃ ┃ ┃ ┣ 📜promiseSection.module.css ┃ ┃ ┃ ┃ ┗ 📜PromiseSection.tsx ┃ ┃ ┃ ┣ 📂_lib ┃ ┃ ┃ ┃ ┗ 📜getPromiseAll.ts ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂recommend ┃ ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┃ ┗ 📜RecommendSection.tsx ┃ ┃ ┃ ┣ 📂_lib ┃ ┃ ┃ ┃ ┗ 📜getUserRecommends.ts ┃ ┃ ┃ ┣ 📜page.tsx ┃ ┃ ┃ ┗ 📜recommend.module.css ┃ ┃ ┣ 📂search ┃ ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┃ ┣ 📜SearchCard.tsx ┃ ┃ ┃ ┃ ┣ 📜SearchForm.tsx ┃ ┃ ┃ ┃ ┗ 📜SearchResult.tsx ┃ ┃ ┃ ┣ 📂_lib ┃ ┃ ┃ ┃ ┗ 📜getSearchResult.ts ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂setting ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂[userId] ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┣ 📜Back.tsx ┃ ┃ ┃ ┣ 📜ImageWithPlaceholder.tsx ┃ ┃ ┃ ┣ 📜LogoutButton.tsx ┃ ┃ ┃ ┣ 📜MainTitle.tsx ┃ ┃ ┃ ┣ 📜MbtiRecommendSection.tsx ┃ ┃ ┃ ┣ 📜Modal.tsx ┃ ┃ ┃ ┣ 📜RQProvider.tsx ┃ ┃ ┃ ┣ 📜SearchForm.tsx ┃ ┃ ┃ ┣ 📜userCard.module.css ┃ ┃ ┃ ┣ 📜UserCard.tsx ┃ ┃ ┃ ┣ 📜UserCardArticle.tsx ┃ ┃ ┃ ┗ 📜UserRandomRecommendSection.tsx ┃ ┃ ┣ 📂_lib ┃ ┃ ┃ ┣ 📜getBase64.ts ┃ ┃ ┃ ┗ 📜getUserRandomRecommends.ts ┃ ┃ ┣ 📜layout.module.css ┃ ┃ ┣ 📜layout.tsx ┃ ┃ ┗ 📜page.tsx ┃ ┣ 📂(beforeLogin) ┃ ┃ ┣ 📂login ┃ ┃ ┃ ┣ 📜login.module.css ┃ ┃ ┃ ┗ 📜page.tsx ┃ ┃ ┣ 📂signup ┃ ┃ ┃ ┣ 📜page.tsx ┃ ┃ ┃ ┗ 📜signup.module.css ┃ ┃ ┣ 📂userSetting ┃ ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┃ ┣ 📜BirthdaySelect.tsx ┃ ┃ ┃ ┃ ┣ 📜DrinkSelect.tsx ┃ ┃ ┃ ┃ ┣ 📜GenderSelect.tsx ┃ ┃ ┃ ┃ ┣ 📜ImageSelect.tsx ┃ ┃ ┃ ┃ ┣ 📜JobSelect.tsx ┃ ┃ ┃ ┃ ┣ 📜MbtiSelect.tsx ┃ ┃ ┃ ┃ ┣ 📜NicknameSelect.tsx ┃ ┃ ┃ ┃ ┣ 📜RegionSelect.tsx ┃ ┃ ┃ ┃ ┣ 📜ReligionSelect.tsx ┃ ┃ ┃ ┃ ┣ 📜SchoolSelect.tsx ┃ ┃ ┃ ┃ ┣ 📜SetUser.tsx ┃ ┃ ┃ ┃ ┣ 📜SetUser2.tsx ┃ ┃ ┃ ┃ ┣ 📜SetUserComplete.tsx ┃ ┃ ┃ ┃ ┣ 📜SetUserProvider.tsx ┃ ┃ ┃ ┃ ┣ 📜SetUserProvider2.tsx ┃ ┃ ┃ ┃ ┣ 📜SetUserTop.tsx ┃ ┃ ┃ ┃ ┣ 📜SmokeSelect.tsx ┃ ┃ ┃ ┃ ┗ 📜TallSelect.tsx ┃ ┃ ┃ ┣ 📜page.tsx ┃ ┃ ┃ ┗ 📜userSetting.module.css ┃ ┃ ┣ 📂_component ┃ ┃ ┃ ┣ 📜title.module.css ┃ ┃ ┃ ┗ 📜Title.tsx ┃ ┃ ┗ 📂_lib ┃ ┃ ┃ ┗ 📜login.ts ┃ ┣ 📂api ┃ ┃ ┗ 📂auth ┃ ┃ ┃ ┗ 📂[...nextauth] ┃ ┃ ┃ ┃ ┗ 📜route.ts ┃ ┣ 📂_component ┃ ┃ ┣ 📜AuthSession.tsx ┃ ┃ ┣ 📜BottomNav.tsx ┃ ┃ ┣ 📜LeftNav.tsx ┃ ┃ ┣ 📜MSWComponent.tsx ┃ ┃ ┣ 📜nav.module.css ┃ ┃ ┗ 📜TopNav.tsx ┃ ┣ 📜favicon.ico ┃ ┣ 📜globals.css ┃ ┗ 📜layout.tsx ┣ 📂components ┃ ┗ 📂ui ┃ ┃ ┣ 📜avatar.tsx ┃ ┃ ┣ 📜badge.tsx ┃ ┃ ┣ 📜button.tsx ┃ ┃ ┣ 📜card.tsx ┃ ┃ ┣ 📜carousel.tsx ┃ ┃ ┣ 📜dropdown-menu.tsx ┃ ┃ ┣ 📜form.tsx ┃ ┃ ┣ 📜input.tsx ┃ ┃ ┣ 📜label.tsx ┃ ┃ ┣ 📜progress.tsx ┃ ┃ ┣ 📜skeleton.tsx ┃ ┃ ┣ 📜textarea.tsx ┃ ┃ ┗ 📜tooltip.tsx ┣ 📂lib ┃ ┗ 📜utils.ts ┣ 📂mocks ┃ ┣ 📜browser.ts ┃ ┣ 📜handlers.ts ┃ ┗ 📜http.ts ┣ 📂model ┃ ┣ 📜Post.ts ┃ ┣ 📜postImage.ts ┃ ┣ 📜User.ts ┃ ┗ 📜UserImage.ts ┣ 📜auth.ts ┗ 📜middleware.ts 로컬에서 잘되다가 어느순간부터 됐다 안됐다 하다가 이제는 안되고 있습니다. 어느 부분을 좀 더 찾아보고 해야할지 조언주시면 정말 감사하겠습니다.

  • react
  • next.js
  • react-query
  • next-auth
  • msw
챠챠_ 댓글 1 좋아요 0 조회수 932

prefetchQuery 적용 후 Warning: Text content did not match. 오류가 발생합니다.

해결됨

Next + React Query로 SNS 서비스 만들기

안녕하세요. 강의 잘 보고 있습니다.!! 👍 👍 react-query를 적용 중 오류가 표시되어 오류와 궁금한 부분이 있어서 문의 드립니다. Text content did not match. 오류가 발생하는데 어느 부분이 문제인지 잘 모르겠습니다 ㅠㅠ prefetchQuery 를 사용하여 서버에서 post(트윗)데이터를 프리패치 후 TweetList컴포넌트에서 useQuery 를 사용하게 만들었습니다. Post의 데이터는 msw에서 알려주신 faker를 통해서 요청마다 content를 동적으로 생성하게 했구요. 콘솔로 출력한 데이터와 reactQuery개발 도구의 데이터는 동일한데 화면에 표기된 데이터는 전혀 다른 데이터로 표시되네요.. 그리고 방식이 prefetchQuery 를 사용한 데이터는 staleTime과 상관없이 Fresh상태로 되어 useQuery 호출 시 데이터가 아직 fresh한 상태이므로 서버를 호출하지 않고 캐쉬에서 가져와 보여주는 방식이 맞나요? 오류로그 app-index.js:33 Warning: Text content did not match. Server: "Tener adulatio decens conitor. Thesis apostolus ago at decerno. Iste uberrime commodo. Verus amitto quas cometes delicate. Cognomen alii curto ciminatio. Solitudo complectus tristis. Teneo sum vindico. Adhuc decimus triumphus ipsa arguo umquam addo adulatio cresco. Sponte degenero non trado cauda beneficium laboriosam approbo." Client: "Tremo collum sint terror templum summisse viduo usque unus benevolentia. Eligendi substantia concido amissio uredo turpis aperte. Admoneo titulus audeo conicio fuga." at div at div at div at article at TweetWrapper (webpack-internal:///(app-pages-browser)/./src/app/(afterLogin)/home/_components/TweetWrapper.tsx:11:11) at Tweet (webpack-internal:///(app-pages-browser)/./src/app/(afterLogin)/home/_components/Tweet.tsx:31:11) at TweetList (webpack-internal:///(app-pages-browser)/./src/app/(afterLogin)/home/_components/TweetList.tsx:16:93) at HydrationBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/@tanstack+react-query@5.39.0_react@18.2.0/node_modules/@tanstack/react-query/build/modern/HydrationBoundary.js:14:11) at HomeContextProvider (webpack-internal:///(app-pages-browser)/./src/app/(afterLogin)/home/_components/Provider.tsx:17:11) at InnerLayoutRouter (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/layout-router.js:242:11) at RedirectErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/redirect-boundary.js:74:9) at RedirectBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/redirect-boundary.js:82:11) at NotFoundBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/not-found-boundary.js:84:11) at LoadingBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/layout-router.js:340:11) at ErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/error-boundary.js:162:11) at InnerScrollAndFocusHandler (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/layout-router.js:152:9) at ScrollAndFocusHandler (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/layout-router.js:227:11) at RenderFromTemplateContext (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/render-from-template-context.js:16:44) at OuterLayoutRouter (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/layout-router.js:359:11) at InnerLayoutRouter (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/layout-router.js:242:11) at RedirectErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/redirect-boundary.js:74:9) at RedirectBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/redirect-boundary.js:82:11) at NotFoundBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/not-found-boundary.js:84:11) at LoadingBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/layout-router.js:340:11) at ErrorBoundary (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/error-boundary.js:162:11) at InnerScrollAndFocusHandler (webpack-internal:///(app-pages-browser)/./node_modules/.pnpm/next@14.1.4_@babel+core@7.24.4_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/client/components/layout-router.js:152:9) at ScrollAndFocu 소스코드 (Tweet이 Post입니다! 나중에 바꿔야겠네여) [page.tsx] /home import React from "react"; import HomeTopTab from "./_components/HomeTopTab"; import WriteForm from "./_components/WriteForm"; import TweetList from "./_components/TweetList"; import HomeContextProvider from "./_components/Provider"; import { QueryClient, dehydrate, HydrationBoundary, } from "@tanstack/react-query"; import getPostRecommends from "./_lib/getPostRecommends"; const HomePage = async () => { const queryClient = new QueryClient(); await queryClient.prefetchQuery({ queryKey: ["tweet", "recommends"], queryFn: getPostRecommends, }); const dehydratedState = dehydrate(queryClient); return ( <HomeContextProvider> <HomeTopTab /> <WriteForm /> <HydrationBoundary state={dehydratedState}> <TweetList /> </HydrationBoundary> </HomeContextProvider> ); }; export default HomePage; TweetList.tsx "use client"; import React from "react"; import Tweet from "./Tweet"; import getPostRecommends from "../_lib/getPostRecommends"; import { Post } from "./TweetWrapper"; import { QueryClient, useQuery } from "@tanstack/react-query"; const TweetList = () => { const { data: tweets } = useQuery<Post[]>({ queryKey: ["tweet", "recommends"], queryFn: getPostRecommends, enabled: false, }); console.log("🚀 _ TweetList _ tweets:", tweets); return tweets?.map((tweet) => <Tweet post={tweet} key={tweet.postId} />); }; export default TweetList;

  • react
  • next.js
  • react-query
  • next-auth
  • msw
홍홍 댓글 2 좋아요 0 조회수 477

찜하기 관련 질문드립니다.

미해결

Next + React Query로 SNS 서비스 만들기

안녕하세요 상세페이지에서 찜하기 요청을 하게되면 users/favorite/${peopleId}로 post 요청을 보내게되고 그럼 users/favorite api에 찜한 사람들의 목록이 추가됩니다. 찜하기를 눌렀을경우 아이콘의 컬러를 변경시켜야해서 getQueryData로 찜한 사람들의 목록 을 가져오려고 하였는데 const { data: likePeopleList } = useQuery<GetPeoples>({ queryKey: ["get", "likepeoples"], queryFn: getLikePeoples, staleTime: 60 * 1000, // fresh -> stale, 5분이라는 기준 gcTime: 300 * 1000, }); 위에 코드가 없으면 likeQuery를 가져오지 못하고있는것같습니다. getQueryData로 가져오는 방법이 잘못된걸까요? 다른 좋은 방법있다면 여쭤보고싶습니다. 밑에는 전체 코드입니다. type Props = { peopleId: string; }; export default function PeoplePosts({ peopleId }: Props) { const { data } = useQuery< GetPeoplePost, Object, GetPeoplePost, [_1: string, _2: string, _3: string] >({ queryKey: ["get", "peoplesDetail", peopleId], queryFn: getPeopleDetail, }); const { data: likePeopleList } = useQuery<GetPeoples>({ queryKey: ["get", "likepeoples"], queryFn: getLikePeoples, staleTime: 60 * 1000, // fresh -> stale, 5분이라는 기준 gcTime: 300 * 1000, }); const { content, nickname, userFileUrl, favoriteCount, viewCount, softSkill, techStack, links, position, alarmStatus, year, } = data?.data ?? {}; const queryClient = useQueryClient(); const likeQuery = queryClient.getQueryData<GetPeoples>([ "get", "likepeoples", ]); console.log("likeQuery", likeQuery); const liked = !!likeQuery?.data.find( (item) => item.userId === Number(peopleId), ); console.log("liked", liked); const like = useMutation({ mutationFn: (peopleId: string) => { return fetch( `${process.env.NEXT_PUBLIC_BASE_URL}/users/favorite/${peopleId}`, { method: "post", }, ); }, onMutate(peopleId: string) { const oldData = queryClient.getQueryData<GetPeoples>([ "get", "likepeoples", ]); if (oldData) { const newData = { ...oldData, data: oldData.data.map((item) => ({ ...item, userId: Number(peopleId), })), }; queryClient.setQueryData(["get", "likepeoples"], newData); } }, }); const unLike = useMutation({ mutationFn: (peopleId: string) => { return fetch( `${process.env.NEXT_PUBLIC_BASE_URL}/users/favorite/${peopleId}`, { method: "delete", }, ); }, onMutate(peopleId: string) { const oldData = queryClient.getQueryData<GetPeoples>([ "get", "likepeoples", ]); if (oldData) { const deleteData = { ...oldData, data: oldData.data.filter((item) => item.userId !== Number(peopleId)), }; queryClient.setQueryData(["get", "likepeoples"], deleteData); } }, }); const onLike: MouseEventHandler<HTMLButtonElement> = (e) => { e.preventDefault(); if (liked) { unLike.mutate(peopleId); } else { like.mutate(peopleId); } }; return ( <div className="flex flex-col"> <div className="flex flex-col gap-4 border-b pb-10"> <div className="flex items-center gap-[10px]"> <Image src={`${userFileUrl}`} alt="유저프로필" width={30} height={30} /> <h1 className="text-[32px] font-bold">{nickname}</h1> <div> <BlueTextBox textSize="12px" textToShow={`${position}`} /> </div> </div> <div className="flex flex-col gap-2"> {softSkill ?.split(",") .map((skill, i) => <HashTag text={skill} key={i} />)} </div> <div className="flex gap-3"> <HeartEyeIconBox count={favoriteCount as number} icon={heartIcon} /> <HeartEyeIconBox count={viewCount as number} icon={eyeIcon} /> </div> </div> <div className="mt-[42px] flex flex-col gap-[50px]"> <div className="people-post-grid"> <h1 className="text-[22px] font-bold">경력</h1> <h3>{year}</h3> </div> <div className="people-post-grid"> <h1 className="text-[22px] font-bold">사용언어</h1> <div className="flex gap-2"> {techStack ?.split(",") .map((stack, i) => ( <TechStack techStack={stack} showText key={`stack${i}`} /> ))} </div> </div> <div className="flex flex-col gap-3"> <h1 className="text-[22px] font-bold">자기소개</h1> <p>{content}</p> </div> <div className="flex flex-col gap-3"> <h1 className="text-[22px] font-bold">Link</h1> <Link href={links as string}>{links}</Link> </div> </div> <div className="mt-[60px] flex gap-[13px] self-center"> <button className={`h-[58px] w-[142px] rounded-md bg-neutral-orange-500 font-bold ${alarmStatus ? "text-neutral-white-0" : "text-neutral-black-800"}`} > {alarmStatus ? "제안하기" : "제안불가"} </button> <button onClick={onLike} className="flex h-[58px] w-[58px] flex-col items-center justify-center rounded-md border" > {liked ? ( <Image src={fillHeartIcon} alt="하트아이콘" width={20} height={20} /> ) : ( <Image src={heartIcon} alt="하트아이콘" width={20} height={20} /> )} <h5 className="text-[12px]">{favoriteCount}</h5> </button> </div> </div> ); }

  • react
  • next.js
  • react-query
  • next-auth
  • msw
댓글 1 좋아요 0 조회수 230

geolocation부분에 대해 질문있습니다.

미해결

[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스

geolocation부분에 const askForLocation = function () { navigator.geolocation.getCurrentPosition((position) => { console.log(position); }); }; askForLocation(); 이렇게 함수가 있는데 여기서 궁금한점이 askForLocation(); 함수 호출부분에 인자로 전달하는 것이 없는데 매개변수로 position에 위치정보 객체형식으로 콘솔에 나오는 이유가 뭔지 궁금합니다.

  • react
  • node.js
  • seo
  • graphql
  • next.js
부드러운 족제비 댓글 3 좋아요 0 조회수 293

3000번은 잘 들어가지는데 80번은 안됩니다.

미해결

따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)

sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000 까지 하고 3000번 포트로 잘 들어가지는데 3000번포트를 지우고 들어가봐도 뒤에 :80을 붙여 넣어 들어가봐도 사이트에 연결할 수 없음이 뜨네요 왜 그럴까요??

  • react
  • node.js
  • postgresql
  • docker
  • typescript
  • 클론코딩
  • next.js
댓글 0 좋아요 1 조회수 316

인기 태그

인프런 TOP Writers

주간 인기글