묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨Next + React Query로 SNS 서비스 만들기
무한 스크롤 prefetch SSR 로그인 쿠키 관련 질문
안녕하세요 제로초님,api/users/{id} 에서 Followers 데이터는제가 상대방을 팔로잉 했고 로그인 정보 쿠키가 잘 전달되면상대방의 팔로워 수와 관계없이 제가 팔로우 했다면 저의 userId만 배열에 담겨서 돌아오기 때문에 api/posts/followings 혹은 api/posts/recommends의Comments 데이터도 이와 동일할 것이라고 생각했습니다. 추천 포스트는 prefetch를 진행하고(Suspense를 적용하지 않음)팔로잉 포스트는 SSR을 할 때 서버에서 로그인 여부를 판단하는 쿠키를 함께 보내야 하기 때문에prefetch에서는 next의 cookies를 사용해서 쿠키를 전달했습니다.하지만 Comments 배열에 로그인 유저가 아닌 다른 유저의 id도 함께 날라옵니다. 추천 포스트가 아닌 팔로잉 포스트는 useSuspenseInfiniteQuery를 사용했는데로그인 유저의 id만 잘 전달받았습니다. 이게 Suspense 내부에 있어서 그런가 싶어서Suspense를 걷어내고 prefetch만 사용했을 때도동일하게 로그인 유저가 아닌 다른 유저의 id도 확인할 수 있었습니다.왜 로그인 쿠키를 보내는데도 다른 유저의 정보도 날라오는지 궁금합니다.어디가 잘못된 것일까요?useSuspenseInfiniteQuery를 사용한 팔로잉 포스트는 추천 포스트와 어떤점이 달라서 정상 작동한 것일까요?추가) 이 글 작성하고 추천 포스트에도 useSuspenseInfiniteQuery를 적용했는데 팔로잉 포스트처럼 안 나오고 이전과 동일하게 다른 유저의 id도 함께 날라오는데 왜 그럴까요? 추천 포스트 결과현재 로그인 한 유저의 id는 'jihwan3'Comments에 'jihwan2'도 함께 날라오는중 팔로잉 포스트 결과현재 로그인 한 유저의 id는 'jihwan3'Comments에 'jihwan3'만 날라오는 중Hearts도 jihwan3가 좋아요를 안 눌러서 비어있는 모습page.tsximport { Suspense } from "react"; import { auth } from "@/auth"; import { Container } from "./_component/styled"; import HomeTab from "./_component/HomeTab"; import HomeTabProvider from "./_component/HomeTabProvider"; import PostForm from "./_component/PostForm"; import SuspenseDecider from "./_component/SuspenseDecider"; import Loading from "../_component/LoadingUI"; export default async function Home() { const session = await auth(); return ( <Container> <HomeTabProvider> <HomeTab></HomeTab> <PostForm me={session} /> <Suspense fallback={<Loading />}> {/* @ts-expect-error Server Component */} <SuspenseDecider /> </Suspense> </HomeTabProvider> </Container> ); } SuspenseDecider.tsximport { QueryClient, HydrationBoundary, dehydrate } from "@tanstack/react-query"; import getRecommendPosts from "../_lib/getRecommendPosts"; import getRecommendPostsServer from "../_lib/getRecommendPostsServer"; import PostDisplay from "./PostDisplay"; export default async function SuspenseDecider() { const queryClient = new QueryClient(); await queryClient.prefetchInfiniteQuery({ queryKey: ["posts", "recommends"], queryFn: getRecommendPostsServer, initialPageParam: 0, getNextPageParam: (lastPage, pages) => lastPage.at(-1)?.postId, pages: 1, }); return ( <HydrationBoundary state={dehydrate(queryClient)}> <PostDisplay /> </HydrationBoundary> ); }getRecommendPostsServer.tsimport { QueryFunction } from "@tanstack/query-core"; import { Post as IPost } from "@/model/Post"; import { cookies } from "next/headers"; type Prop = { pageParam: number; }; const getRecommendPostsServer: QueryFunction<IPost[], [_1: string, _2: string], number> = async ({ pageParam }: Prop) => { const response = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/posts/recommends?cursor=${pageParam}`, { method: "get", headers: { Cookie: cookies().toString(), }, }); if (response.ok) return response.json(); else throw new Error(); }; export default getRecommendPostsServer;postDisplay.tsx"use client"; import { use } from "react"; import { TabContext } from "./HomeTabProvider"; import RecommendPosts from "./RecommendPosts"; import FollowingPosts from "@/app/(afterLogin)/home/_component/FollowingPosts"; export default function PostDisplay() { const { selectedMenu } = use(TabContext); if (selectedMenu === "recommend") { return <RecommendPosts />; } return <FollowingPosts />; } RecommendPosts.tsx"use client"; import { useEffect, Fragment } from "react"; import { InfiniteData, useInfiniteQuery } from "@tanstack/react-query"; import { useInView } from "react-intersection-observer"; import getRecommendPosts from "../_lib/getRecommendPosts"; import Post from "../../_component/Post"; import { Post as IPost } from "@/model/Post"; export default function RecommendPosts() { const { isFetching, fetchNextPage, hasNextPage, data } = useInfiniteQuery<IPost[], Object, InfiniteData<IPost[]>, [_1: string, _2: string], number>({ queryKey: ["posts", "recommends"], queryFn: getRecommendPosts, initialPageParam: 0, getNextPageParam: (lastPage) => lastPage.at(-1)?.postId, }); const { ref, inView } = useInView({ /* Optional options */ threshold: 0, delay: 100, }); useEffect(() => { if (inView) !isFetching && hasNextPage && fetchNextPage(); }, [inView, isFetching, hasNextPage, fetchNextPage]); if (!data) return null; // 이거 에러는...? type error인데.. -> InfiniteData로 해결 return ( <> {data.pages.map((ele: IPost[], idx: number) => ( <Fragment key={idx}> {ele.map((post: IPost) => ( <Post key={post.postId} post={post}></Post> ))} </Fragment> ))} <div ref={ref} style={{ height: "50px" }}></div> </> ); } getRecommendPost.tsimport { QueryFunction } from "@tanstack/query-core"; import { Post as IPost } from "@/model/Post"; type Prop = { pageParam: number; }; const getRecommendPosts: QueryFunction<IPost[], [_1: string, _2: string], number> = async ({ pageParam }: Prop) => { const response = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/posts/recommends?cursor=${pageParam}`, { method: "get", credentials: "include", }); if (response.ok) return response.json(); else throw new Error(); }; export default getRecommendPosts; FollowingPosts.tsx"use client"; import { Fragment, useEffect } from "react"; import { useSuspenseInfiniteQuery, InfiniteData } from "@tanstack/react-query"; import { useInView } from "react-intersection-observer"; import getFollowingPosts from "../_lib/getFollowingPosts"; import Post from "../../_component/Post"; import { Post as IPost } from "@/model/Post"; export default function FollowingPosts() { const { isFetching, fetchNextPage, hasNextPage, data } = useSuspenseInfiniteQuery<IPost[], Object, InfiniteData<IPost[]>, [_1: string, _2: string], number>({ queryKey: ["posts", "followings"], queryFn: getFollowingPosts, initialPageParam: 0, getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => lastPage.at(-1)?.postId, }); const { ref, inView } = useInView({ threshold: 0, delay: 100, }); useEffect(() => { if (inView) !isFetching && hasNextPage && fetchNextPage(); }, [inView, fetchNextPage, hasNextPage, isFetching]); if (!data) return null; return ( <> {data.pages.map((ele: IPost[], idx: number) => ( <Fragment key={idx}> {ele.map((ele) => ( <Post key={ele.postId} post={ele}></Post> ))} </Fragment> ))} <div ref={ref} style={{ height: "100px" }}></div> </> ); }
-
해결됨실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트
mockServiceWorker.js 파일이 프로젝트내에 포함되어 있어야 하나요?
실무에 적용하려고 하니 msw 에서 많이 막히네요 ㅠ 그래서 올려주신 깃헙 프로젝트를 샅샅히 훑어보고 있는데 mockServiceWorker.js 이 파일과 package.json에"msw": { "workerDirectory": "public" } 요런 부분이 있더라고요. 요것들의 역할이 뭔지 알수 있을까요? msw 사이트에 가서 Getting started 를 가봐도 안나와 있는것 같아서 궁금합니다!
-
미해결[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
회원가입 과제 완료용
안녕하세요!!과제 완료해서 피드백 부탁드리고자 올렸습니다!앞으로 잘 부탁 드립니당~<html><!DOCTYPE html> <html lang="ko"> <head> <title>회원가입</title> <link rel="stylesheet" href="./02-signup.css"> </head> <body> <div class="signUpContent"> <h2> 회원 가입을 위해<br> 정보를 입력해주세요 </h2> <label for="email" class="label text">* 이메일</label> <input id="email" class="input_text" type="text"> <label for="name" class="label text">* 이름</label> <input id="name" class="input_text" type="text"> <label for="password" class="label text">* 비밀번호</label> <input id="password" class="input_text" type="password"> <label for="password_chk" class="label text">* 비밀번호 확인</label> <input id="password_chk" class="input_text" type="password"> <div class="signUpChk"> <input id="gender_w" class="input_radio" type="radio" name="gender"> <label for="gender_w" class="label gender">여성</label> <input id="gender_m" class="input_radio" type="radio" name="gender"> <label for="gender_m" class="label gender">남성</label> </div> <div class="agreeChk"> <input type="checkbox" id="input_chk"> <span class="agree_text"> 이용약관 개인정보 수집 및 이용, 마케팅 활용 선택에 모두 동의합니다. </span> </div> <div class="out-line"> <div class="line"></div> </div> <button> <span>가입하기</span> </button> </di> </body> </html><css>* { box-sizing: border-box; } h2 { font-size: 32px; color: #0068FF; font-weight: 700; line-height: 47px; } .out-line{ padding: 30px 0px; } .line { border-bottom: 1px solid #E6E6E6; } .label{ font-size: 16px; font-weight: 400; line-height: 24px; } .signUpContent{ width: 670px; height: 960px; border: 1px solid #AACDFF; border-radius: 20px; box-shadow: 7px 7px 39px rgba(0, 104, 255, .25) ; display: flex; flex-direction: column; padding: 72px 100px 70px 100px; } .label.text{ padding: 20px 20px 0 0; color: #797979; } .input_text{ border-style: none; border-bottom: 1px solid #CFCFCF; height: 60px; } .signUpChk{ display:flex; justify-content: center; align-items: center; padding: 50px 0; } .input_radio{ margin: 0 5px 0 0; width: 20px; height: 20px; } .label.gender{ padding-right: 30px; } .agreeChk{ display: flex; justify-content: center; align-items: center; } .agree_text{ height: 22px; font-size: 14px; font-weight: 400; line-height: 20px; } button{ width: 470px; height: 75px; background-color: #FFF; border: 1px solid #0068FF; border-radius: 10px; } button > span { font-size: 18px; font-weight: 400; color: #0068FF; }
-
해결됨기초부터 배우는 Next YTMusic 클론 코딩 (with next.js 14, UI 마스터)
changer라는 컴포넌트를 사용하는 이유
HeaderBgChanger라는 컴포넌트는 단순히 서버 컴포넌트에서 react hook을 사용할 수 없기 때문에 만드는 컴포넌트인지 궁금합니다.또 이렇게 컴포넌트를 만들 경우에 렌더링 될 때 영향을 주는 부분은 없는지 궁금합니다.
-
미해결Next + React Query로 SNS 서비스 만들기
Nextjs fetch, react-query 캐시 개념
Nextjs fetch도 캐시가 지원되고, react-query도 캐시가 지원되는걸로 이해를 했는데요 문득 궁금한 점이 생겨서 질문 드립니다. Nextjs fetch와 react-query에서의 캐시는 같은 개념인가요? 아니면 서로 다른 개념인가요?왜 Nextjs fetch를 안 쓰고 react-query를 쓰는 걸까요?Nextjs fetch는 어떨 때 쓰고 react-query는 어떨 때 쓰는 건가요?감사합니다.
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
Entity에 ElementCollection이 두 개 있는 경우
안녕하세요! 하나의 엔티티에 @ElementCollection 붙은 필드가 두 개 있는 경우를 시험해 보고 있습니다. @EntityGraph(attributePaths = {"a", "b"}) 이런 식으로 해서 테스트를 돌리면 org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags 과 같은 오류가 나는데 ElementCollection 두 개가 있는 경우는 하나의 쿼리로 모두 가져오는 방법은 없나요?
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
Encountered two children with the same key
Multer 이용하여 이미지 업로드 하면 다음 오류가 뜹니다 import React from 'react' import Dropzone from 'react-dropzone' import axiosInstance from '../utils/axios'; import PropTypes from 'prop-types'; const FileUpload = ({ onImageChange, images }) => { const handleDrop = async (files) => { let formData = new FormData(); const config = { header: { 'content-type': 'multipart/form-data' } } formData.append('file', files[0]); try { const response = await axiosInstance.post('/products/image', formData, config); onImageChange([...images, response.data.fileName]); } catch (error) { console.error(error); } } return ( <div className='flex gap-4'> <Dropzone onDrop={handleDrop}> {({ getRootProps, getInputProps }) => ( <section className='min-w-[300px] h-[300px] border flex items-center justify-center' > <div {...getRootProps()}> <input {...getInputProps()} /> <p className='text-3xl'>+</p> </div> </section> )} </Dropzone> {images.map((image, index) => ( <div key={image+index}> {/* image 이름과 index를 조합하여 고유한 키를 생성 */} <img className='min-w-[300px] h-[300px]' src={`${import.meta.env.VITE_SERVER_URL}/${image}`} alt={image} /> </div> ))} </div> ) } FileUpload.propTypes = { // onImagesChnage: PropTypes.bool.isRequired, onImageChange: PropTypes.any, images: PropTypes.any, }; export default FileUpload
-
해결됨기초부터 배우는 Next YTMusic 클론 코딩 (with next.js 14, UI 마스터)
컴포넌트 만들때에는 jsx를 사용하는 이유?
안녕하세요. 강의를 수강중인 수강생입니다.혹시 컴포넌트들을 만들때엔 타입스크립트 tsx가 아닌 jsx를 사용하시는데, 이러한 이유가 있을까요? 추가적으로 React.FC에 대해 공부하다보니 지양한다는 글들이 많은데, 어떻게 생각하시는지 궁금합니다. 감사합니다.
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
map 함수에서 cannot read properties of undefined 에러 발생
강사님이 알려주신 대로 작성했는데 해당 부분에서 Cannot read properties of undefined (reading 'map') 이라는 오류가 발생합니다.ㅠㅠ 오타가 있는것 같지는 않은데..어디가 문제일까요..?
-
해결됨기초부터 배우는 Next YTMusic 클론 코딩 (with next.js 14, UI 마스터)
Hot reload 오류 문의 드립니다.
안녕하세요강사님은 코드 수정 후 브라우저에서 바로바로 확인이 되는 것 같은데 저는 코드를 수정할 때 마다 아래의 오류가 발생해서 매번 다시 yarn dev를 해줘야 수정한 내역이 확인이 되다 보니 강의를 따라 진행 하는대 집중이 되질 않네요. 혹시 아래의 에러가 발생 되지 않게 하는 방법이 있는 것인지 문의 드립니다.감사합니다.수고하세요.===================================================================⨯ [Error: UNKNOWN: unknown error, open 'D:\study\react\workspace\yt-music-clone-next\.next\static\chunks\app\layout.js'] {errno: -4094,code: 'UNKNOWN',syscall: 'open',path: 'D:\\study\\react\\workspace\\yt-music-clone-next\\.next\\static\\chunks\\app\\layout.js'===================================================================
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
오픈그래프 태그
배포 후 링크 공유하는데 오픈 그래프 태그가 나타나지 않습니다.ㅜㅜ
-
미해결파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트 (장고 4.2 기준)
관련 책이 언제 나올까요?
관련 도서 출간은 언제쯤 예상하시나요?건강하시길 바라요~
-
해결됨기초부터 배우는 Next YTMusic 클론 코딩 (with next.js 14, UI 마스터)
멀티 선택 단축키
2분 50초쯤에서 멀티선택 하는 방법 알려주시면 감사하겠습니다!!
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
리랜더링 highLight 질문..
10.3) React.memo와 컴포넌트 렌더링 최적화위 강의를 보다보니, 뭔가 이상해서 질문드립니다...여기서 Header컴포넌트에 memo함수로 감싸서최적화된 컴포넌트를 만드셨다고 했는데, 영상으로만 보면item 컴포넌트 변경시에 리랜더링이 안되야 하는 Header 컴폰넌트에 highLight가 들어가는데요..(4:46 경..)아무리 봐도 하이라이트가 들어가는데, 말씀으로는 하이라이트가 더이상 들어가지 않는다고 하는데, 제가 뭘 잘못 이해한걸까요?
-
해결됨코드로 배우는 React 19 with 스프링부트 API서버
노란색 경고글을 없애고 싶어요..
프론트 부분에서 ESLint 때문에 계속 에러를 겪고 있는데요,,해결했다 싶으면 신기하게도 다음번 컴퓨터를 키면 또 에러가 생겨있고 그러는데요,빨간색 에러는 없앴는데 노란색 경고글도 없애고 싶습니다.아래 노란색 경고글들도 없앨수 있는 방법이 있을까요...에러때문에 이것저것 시도하다가 뭔가 버전이 안맞는 걸까요...
-
해결됨Next + React Query로 SNS 서비스 만들기
useQuery vs useQueryClient
tanstack query와 next.js 를 함께 사용하면서 의문이 들어 질문합니다!강의의 코드를 보니 같이 prefetch를 해도 유저데이터는 useQueryClient를 사용해서 데이터를 재사용하는듯한데 안에 하위 컴포넌트의 경우 prefetch를하고 useQuery를 사용해서 데이터를 가져오는듯 하더라구요 이 경우도 데이터를 재사용하는건가요? 아니면 새로 가져오는건가요? 그렇다면 똑같이 데이터를 prefetch해도 useQueryClient를 사용해서 가져오는것과 useQuery를 사용해서 가져와야하는 기준이 있을까요? (저의경우 프로젝트 전체를 prefetch후 useQueryClient를해서 데이터를 가져왔더니 데이터를 가져옴과 동시에 fresh가아니라 inactive상태가 되더라구요. ) 좋은강의 감사합니다. 벚꽃같은 제로초 화이팅
-
해결됨기초부터 배우는 Next YTMusic 클론 코딩 (with next.js 14, UI 마스터)
웹사이트에서 바로 한글로 번역되는거 어떤 프로그램쓰시는건가요?
안녕하세요. 처음 15초쯤에 nextjs소개하면서 나오는 번역프로그램은 어떤걸 쓰시는건가요? 편리해보여서요~
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
Prettier 적용 안되는 이슈
강의에서 소개해주신 것 처럼 Format on Save 옵션을 적용하였는데도, 저장 시 자동으로 Formatter가 작동하지 않아 서치해보니,Default Formatter 옵션이 위처럼 없음(null)로 설정이 된 경우에는 Prettier로 적용해주어야 정상동작하더라구요.해당 내용 공유드려요 ㅎ
-
미해결
javascript 공부없이 바로 react native 배워도 되나요?
html/css, jQuery, Java Script, react까지 3년전에 배웠었어요.현재는 html/css 코드를 보고 읽고 간단한 건 수정할 수 있는 정도의 수준입니다. 개인적인 흥미로 취미로 개발을 배워보고 싶은데 시작하면 앱 개발, 유지/보수 할 수 있는 수준으로는 배우고 싶어요. 과외로 배울 예정인데 2분의 선생님을 소개받았는데 어떤 분의 루트가 더 나을지 판단이 어려워 전문가분들의 의견 구합니다.html/css > Java > react > react native까지 차근히 배우는 선생님React native와 Java Script를 병행으로 배우는 선생님 1번 선생님의 경우, 현직자이신 것 같진 않고 강의를 위주로 하시는 분 같고 2번 선생님은 현직 개발자로 7년차이세요. 2번 선생님의 경우 함수선언을 영어로 치면 숙어라고 생각하고 배울 수 있을 것 같다고 설명해주셨어요. 리엑트 네이티브에서 사용했던 언어들이 java Script에서 조금 변형된 것들이라고 기억하고 있어서 2번 선생님이 더 속성으로 배울 수 있을 것 같긴 한데(기간은 1년정도 생각합니다) 나중에 혼자 앱 개발을 하는 상황을 생각하면 처음부터 꼼꼼히 배우는게 나을까요?
-
해결됨React + GPT API로 AI회고록 서비스 개발 (원데이 클래스)
프롬프트 내용은 어디서 볼수있나요?
안녕하세요 강사님 강의 정말 잘 듣고있습니다.다름이 아니라 프롬프트의 내용이 꽤 긴데 혹시 복붙할 수 있는 페이지는 따로 없는지 궁금합니다..! 제가 못찾은것일수도 있어서 조심스럽게 문의드립니다