묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Next + React Query로 SNS 서비스 만들기
metadata
안녕하세요 복습중에 있는데 검색해도 잘모르는내용이라 내용 적어봅니다.넥스트를 배우려는 큰이유중 하나가 SEO 때문인데 넥스트에서 metadata 페이지마다 꼬박꼬박 잘적고 (title ,desc)시맨태그 최대한 이용해서 마크업하면 끝인가요 ?넥스트 내에서 더 해줘야하는 작업이라던가.. 그런게 있을까요 ? (구글 서치콘솔 이런거 말고.. 개발자가 코드 작업시에 놓치면안되는 요구 SEO 작업이 궁금해서요 )
-
미해결Next + React Query로 SNS 서비스 만들기
public 경로
초보적인질문입니다. src기준이니깐 @못쓴다면 public 기준은 ../../../../ 이런식으루 사용해야할까요 ?
-
미해결Next + React Query로 SNS 서비스 만들기
[섹션3] useFormState, 이 호출과 일치하는 오버로드가 없습니다. 에러
"use client"; import style from './signup.module.css'; import onSubmit from '../_lib/signup'; import BackButton from "@/app/(beforeLogin)/_component/BackButton"; import { useFormState, useFormStatus } from 'react-dom'; export default function SignupModal() { const [state, formAction] = useFormState(onSubmit, { message: null }); const { pending } = useFormStatus();[섹선3] 클라이언트 컴포넌트에서 Server Actions 사용하기, 3분 const [state, formAction] = useFormState(onSubmit, { message: null });이쪽부분에[이 호출과 일치하는 오버로드가 없습니다.]라는 빨간에러가 뜨는데 혹시 이유를 알 수 있을까요? [제로초 강좌 질문 필독 사항입니다]질문에는 여러분에게 도움이 되는 질문과 도움이 되지 않는 질문이 있습니다.도움이 되는 질문을 하는 방법을 알려드립니다.https://www.youtube.com/watch?v=PUKOWrOuC0c0. 숫자 0부터 시작한 이유는 1보다 더 중요한 것이기 때문입니다. 에러가 났을 때 해결을 하는 게 중요한 게 아닙니다. 왜 여러분은 해결을 못 하고 저는 해결을 하는지, 어디서 힌트를 얻은 것이고 어떻게 해결한 건지 그걸 알아가셔야 합니다. 그렇지 못한 질문은 무의미한 질문입니다.1. 에러 메시지를 올리기 전에 반드시 스스로 번역을 해야 합니다. 번역기 요즘 잘 되어 있습니다. 에러 메시지가 에러 해결 단서의 90%를 차지합니다. 한글로 번역만 해도 대부분 풀립니다. 그냥 에러메시지를 올리고(심지어 안 올리는 분도 있습니다. 저는 독심술사가 아닙니다) 해결해달라고 하시면 아무런 도움이 안 됩니다.2. 에러 메시지를 잘라서 올리지 않아야 합니다. 입문자일수록 에러메시지에서 어떤 부분이 가장 중요한 부분인지 모르실 겁니다. 그러니 통째로 올리셔야 합니다.3. 코드도 같이 올려주세요. 다만 코드 전체를 다 올리거나, 깃헙 주소만 띡 던지지는 마세요. 여러분이 "가장" 의심스럽다고 생각하는 코드를 올려주세요.4. 이 강좌를 바탕으로 여러분이 응용을 해보다가 막히는 부분, 여러 개의 선택지 중에서 조언이 필요한 부분, 제 경험이 궁금한 부분에 대한 질문은 대환영입니다. 다만 여러분의 회사 일은 질문하지 마세요.5. 강좌 하나 끝날 때마다 남의 질문들을 읽어보세요. 여러분이 곧 만나게 될 에러들입니다.6. 위에 적은 내용을 명심하지 않으시면 백날 강좌를 봐도(제 강좌가 아니더라도) 실력이 늘지 않고 그냥 코딩쇼 관람 및 한컴타자연습을 한 셈이 될 겁니다.
-
해결됨Next + React Query로 SNS 서비스 만들기
memurai 설치가 안됩니다..
안녕하세요 제로초님 postgreSQL까지는 설치하고 데이터베이스 설정도 되었는데memurai 는 아래 오류가 뜨면서 설치부터 안됩니다.해결방법을 찾지 못해서 질문 드립니다..
-
미해결Next + React Query로 SNS 서비스 만들기
fetch 함수에 searchParams.toString() 사용 관련
export const getSearchResult : QueryFunction<Post[], [_1 : string, _2 : string, searchParams : {q : string, pf? : string, f? : string> = async ({queryKey}) =>{ const res = await fetch(`http://localhost:9090/api/search/$ {searchParams.toString()? ${searchParams.toString()}` 여기서 searchParams는 객체 타입인데 toString() 처리가 가능한지 궁금합니다.
-
미해결Next + React Query로 SNS 서비스 만들기
패레럴 라우트와 인터셉터 라우트를 공부하다 생긴 의문점입니다.
안녕하세요 제로초님 강의를 듣다 의문점이 하나 생겨 질문드립니다. 패레럴 라우트와 인터셉터 라우트를 사용해서 모달을 띄우는 방법을 알려주셨는데 기존의 react에서 사용하던 방식으로 모달의 띄우는게 더 코드도 단순하고 간단하게 구현할 수 있을것 같은데 nextjs에서는 페레럴 라우트와 인터셉터 라우트를 사용해서 모달을 구현하는게 어떤 이점이 있는지 궁금합니다.기존의 모달을 띄우는 방법은 여러가지가 있지만 state를 통해서 구현하거나 queryString을 사용해서 구현할 수 있을것 같습니다.queryString을 사용하면 뒤로가기 버튼클릭시 모달을 띄우기전 url로도 이동할 수 있고 새로고침을 해도 모달과 뒤의 배경을 같이 보여줄 수 있을 것 같습니다.혼자서 생각도 해보고 인터넷에서 자료도 찾아봤지만 정확한 이유를 잘 모르겠어서 질문드립니다. 오늘도 좋은 하루 되셨으면 좋겠습니다. 감사합니다.
-
미해결Next + React Query로 SNS 서비스 만들기
인터셉팅 라우트
인터셉팅 라우트의 본 목적은 아닌 것 같으나 제 생각으론 가능하지 않을까 하는 생각이 드는데 진짜 가능한 건지 궁금해서 여쭤봅니다,,ㅠㅠ 인터셉팅 시에 모달이 뜨면서 children이 변경되도록 하고 싶은데,,, 가능한 건가요,,? 그러면 폴더 경로를 어떻게 설정 해야 할까요,,?
-
해결됨[리뉴얼] 맛집 지도앱 만들기 (React Native & NestJS)
Presigned URL 방식
강사님이 알려주신 방식을 듣고 다양한 이미지 처리 방식을 공부하기 위하여 Presigned URL 방식을 구현중에 있습니다. Nest.js 백엔드에 요청을 통해 발급받은 S3 url 주소에 RN환경에서 PUT 요청으로 이미지를 업로드하고 있습니다. 이 떄, 일반적인 form-data 형식은 들어가지지 않는 것 같은데, binary 형태는 매우 잘 들어가집니다.현업에서도 presigned-url을 활용할 떄 binary 형태로만 전달을 해야하나요, 아니면 다른 방식이 있는지 알고 싶어 식견을 구하고자, 질문드립니다!!또, RN에서 Binary 형태를 만드는 방법이 쉽지 않아보여, 어떻게 하는게 좋은 방식인지 알고싶습니다!
-
해결됨[풀스택 완성] Supabase로 웹사이트 3개 클론하기 (Next.js 14)
Client provider in layout.tsx - 어떻게 동작하나요?
강사님 강의를 이제 막 듣기 시작한 수강생입니다!지금 리코일 기본 문법 관련 강의를 듣던중 궁금증이 생겨 질문드립니다.클라이언트 페이지 하위의 페이지는 모두 클라이언트 페이지로 바뀌는 것으로 이해하고 있었는데전역에 리코일 프로바이더로 감싸주는 형태로 사용하게 되면 부분적으로 클라이언트 페이지가 되는 것인가요?!어떻게 이해하면 좋을지 궁금합니다!
-
해결됨[리뉴얼] 맛집 지도앱 만들기 (React Native & NestJS)
gradle 오류
윈도우 amd 안드로이드 환경입니다react-native doctor를 했을땐 이상이 없는데npm start 했을 때 Gradle could not start your build. Could not create service of type ChecksumService using BuildSessionScopeServices.createChecksumService(). java.io.FileNotFoundException: C:\Users\project\MatzipApp\android.gradle\8.0.1\checksums\checksums.lock (������ �źεǾ����ϴ�) 이런 오류가 자꾸 뜹니다
-
해결됨[리뉴얼] 맛집 지도앱 만들기 (React Native & NestJS)
템플릿 리터럴 오류 질문
윈도우, 안드로이드 환경입니다.import React from 'react'; import {Pressable, StyleSheet, Text} from 'react-native'; interface CustomButtonProps{ label: string; variant?: 'filled' | 'outlined'; size?: 'large' | 'medium'; } function CustomButton({ label, variant='filled', size='large', }: CustomButtonProps) { return ( <Pressable style={[styles.container, styles[variant], styles[size]]}> <Text style={[styles.text, styles['${variant}Text']]}>{label}</Text> </Pressable> ) } const styles = StyleSheet.create({ container:{ borderRadius: 3, justifyContent:'center', }, filled: { backgroundColor:'#C63B64' }, outlined: { borderColor:'C63B64', borderWidth: 1, }, large: { width: '100%', paddingVertical: 15, alignItems: 'center', justifyContent: 'center', }, medium: { width: '50%', paddingVertical: 12, alignItems: 'center', justifyContent: 'center', }, text: { fontSize: 16, fontWeight: '700', }, filledText: { color: 'white', }, outlinedText: { color: '#C63B64', }, }); export default CustomButton;styles['${variant}Text' ]이 부분이 에러가 발생하는데 왜그런 것인가요?에러메세지는 다음과 같습니다.[{"resource": "/c:/Users/dcgn6ec/MatzipApp/front/src/components/CustomButton.tsx","owner": "typescript","code": "7053","severity": 8,"message": "Element implicitly has an 'any' type because expression of type '\"${variant}Text\"' can't be used to index type '{ container: { borderRadius: number; justifyContent: \"center\"; }; filled: { backgroundColor: string; }; outlined: { borderColor: string; borderWidth: number; }; large: { width: \"100%\"; paddingVertical: number; alignItems: \"center\"; justifyContent: \"center\"; }; medium: { ...; }; text: { ...; }; filledText: { ...; }; ...'.\n Property '${variant}Text' does not exist on type '{ container: { borderRadius: number; justifyContent: \"center\"; }; filled: { backgroundColor: string; }; outlined: { borderColor: string; borderWidth: number; }; large: { width: \"100%\"; paddingVertical: number; alignItems: \"center\"; justifyContent: \"center\"; }; medium: { ...; }; text: { ...; }; filledText: { ...; }; ...'.","source": "ts","startLineNumber": 18,"startColumn": 36,"endLineNumber": 18,"endColumn": 60}]
-
미해결Next + React Query로 SNS 서비스 만들기
3장_ next-auth 로그인하기 / 로그인 시 ID,Password 정보 어디에 있나요?
마지막에 로그인시저는 http://localhost:3000/api/auth/error"이 페이지는 존재하지 않습니다. 다른 페이지를 검색해 보세요검색" 위 URL로 리다이렉트 되고 해당 ㅁㅔ시지가 뜹니다.혹시 어디에 있는 정보로 로그인하는건지 궁금합니다
-
해결됨[풀스택 완성] Supabase로 웹사이트 3개 클론하기 (Next.js 14)
react query의 mutationfn과 queryfn관련 질문입니다.
왜 mutationfn은 비동기 함수를 할당해주고 async () => {return createTodo(todoInput)} 왜 queryfn은 그냥 일반 함수를 할당한건가요?() => getTodo(), 차이가 무엇인지 궁금합니다.
-
미해결Next + React Query로 SNS 서비스 만들기
fetch 옵션에 cache no-store 사용하면 tags 사용안해도 되는거 아닌가요???
export async function getSearchResult({ queryKey }) { const [_1, _2, searchParams] = queryKey; const res = await fetch(api url, next: { tags: ["posts", "search", searchParams] }, cache: 'no-store' )}next tags를 사용하는이유가 revalidate를 하기 위해서인데fetch 옵션을 'no-store'로 주면 캐시가 되지 않는걸로 알고있어서 tags 사용안해도 되지않나요??
-
미해결Next + React Query로 SNS 서비스 만들기
개인 포폴작업중인데 백엔드 인가를 어떤식으로 구현해야할까요..
제로초님의 next-auth 작업하시는걸 보고 프론트에서 next-auth로 로그인하는것을 구현을 하긴 했는데 로그인(인가)을 하는 주체가 프론트다 보니 기존에 배웠을때는 nest 또는 node에서 passport를 이용해서 작업을 했엇는데 이제는 passport로 인가 하는 작업이 필요가 없어진건지 궁금합니니다.필요가 없다라고 하면 백엔드서버에서는 이사람이 로그인을 했는지 안했는지를 알아야 할텐데 그거는 어떻게 구현을 해야할지가 막막해서 질문드립니다 ㅠㅠ
-
해결됨[풀스택 완성] Supabase로 웹사이트 3개 클론하기 (Next.js 14)
Supabase Storage .emptyFolderPlaceholder 이슈 (슬랙)
https://github.com/supabase/storage/issues/207모든 파일을 제거했을 때 갑자기 .emptyFolderPlaceholder가 파일 리스트에 나오는 문제입니다.슬랙에 올라온 질문인데 같은 이슈를 겪는 분들이 종종 계실 것 같아 인프런 커뮤니티에도 해결책을 공유드립니다.
-
해결됨[풀스택 완성] Supabase로 웹사이트 3개 클론하기 (Next.js 14)
react-query 무한스크롤 staleTime caching 질문 (슬랙)
Slack에 올라온 질문이 좋아서 인프런 커뮤니티에도 공유드립니다.
-
미해결Next + React Query로 SNS 서비스 만들기
2장 클론 코딩시 화면 하단에 회색 영역이 생김니다.
강좌와 git을 보면서 했는데,왜 아래에 회색영역이 생기는 건지 잘 모르겠습니다.ㅜㅜ세로로 생기는 스크롤도 흰색영역에만 생깁니다.그런데 로그아웃버튼은 회색영역에 생기네요이리저리 해봐도 잘 모르겠어서 도움을 요청합니다
-
미해결Next + React Query로 SNS 서비스 만들기
서로 다른 컴포넌트간 query 일치하게 하기 강의중
안녕하세여 제로초님 UserInfo에서 팔로우버튼을 누르면 팔로잉으로 변해야되고 다시 한번 누르면 팔로우로 변해야되는데 버튼을 누르고 새로고침을 해야지만 반영이됩니다... 팔로우 추천에서는 바로 반영이 되는데....깃허브 ch3-2 UserInfo에 있는 코드로 가져다 써도 안되네여 ㅠㅠ"use client"; import style from "@/app/(afterLogin)/[username]/profile.module.css"; import BackButton from "@/app/(afterLogin)/_component/BackButton"; import { useQuery, useQueryClient, useMutation } from "@tanstack/react-query"; import { User } from "@/model/User"; import { getUser } from "@/app/(afterLogin)/[username]/_lib/getUser"; import cx from "classnames"; import { MouseEventHandler } from "react"; import { Session } from "@auth/core/types"; type Props = { username: string; session: Session | null; }; export default function UserInfo({ username, session }: Props) { const { data: user, error } = useQuery< User, Object, User, [_1: string, _2: string] >({ queryKey: ["users", username], queryFn: getUser, staleTime: 60 * 1000, // fresh -> stale, 5분이라는 기준 gcTime: 300 * 1000, }); const queryClient = useQueryClient(); const follow = useMutation({ mutationFn: (userId: string) => { console.log("follow", userId); return fetch( `${process.env.NEXT_PUBLIC_BASE_URL}/api/users/${userId}/follow`, { credentials: "include", method: "post", } ); }, onMutate(userId: string) { const value: User[] | undefined = queryClient.getQueryData([ "users", "followRecommends", ]); if (value) { const index = value.findIndex((v) => v.id === userId); if (index > -1) { console.log(value, userId, index); const shallow = [...value]; shallow[index] = { ...shallow[index], Followers: [{ id: session?.user?.email as string }], _count: { ...shallow[index]._count, Followers: shallow[index]._count?.Followers + 1, }, }; queryClient.setQueryData(["users", "followRecommends"], shallow); } } const value2: User | undefined = queryClient.getQueryData([ "users", userId, ]); if (value2) { const shallow: User = { ...value2, Followers: [{ id: session?.user?.email as string }], _count: { ...value2._count, Followers: value2._count?.Followers + 1, }, }; queryClient.setQueryData(["users", userId], shallow); } }, onError(error, userId: string) { console.error(error); const value: User[] | undefined = queryClient.getQueryData([ "users", "followRecommends", ]); if (value) { const index = value.findIndex((v) => v.id === userId); console.log(value, userId, index); if (index > -1) { const shallow = [...value]; shallow[index] = { ...shallow[index], Followers: shallow[index].Followers.filter( (v) => v.id !== session?.user?.email ), _count: { ...shallow[index]._count, Followers: shallow[index]._count?.Followers - 1, }, }; queryClient.setQueryData(["users", "followRecommends"], shallow); } const value2: User | undefined = queryClient.getQueryData([ "users", userId, ]); if (value2) { const shallow = { ...value2, Followers: value2.Followers.filter( (v) => v.id !== session?.user?.email ), _count: { ...value2._count, Followers: value2._count?.Followers - 1, }, }; queryClient.setQueryData(["users", userId], shallow); } } }, }); const unfollow = useMutation({ mutationFn: (userId: string) => { console.log("unfollow", userId); return fetch( `${process.env.NEXT_PUBLIC_BASE_URL}/api/users/${userId}/follow`, { credentials: "include", method: "delete", } ); }, onMutate(userId: string) { const value: User[] | undefined = queryClient.getQueryData([ "users", "followRecommends", ]); if (value) { const index = value.findIndex((v) => v.id === userId); console.log(value, userId, index); if (index > -1) { const shallow = [...value]; shallow[index] = { ...shallow[index], Followers: shallow[index].Followers.filter( (v) => v.id !== session?.user?.email ), _count: { ...shallow[index]._count, Followers: shallow[index]._count?.Followers - 1, }, }; queryClient.setQueryData(["users", "followRecommends"], shallow); } const value2: User | undefined = queryClient.getQueryData([ "users", userId, ]); if (value2) { const shallow = { ...value2, Followers: value2.Followers.filter( (v) => v.id !== session?.user?.email ), _count: { ...value2._count, Followers: value2._count?.Followers - 1, }, }; queryClient.setQueryData(["users", userId], shallow); } } }, onError(error, userId: string) { console.error(error); const value: User[] | undefined = queryClient.getQueryData([ "users", "followRecommends", ]); if (value) { const index = value.findIndex((v) => v.id === userId); console.log(value, userId, index); if (index > -1) { const shallow = [...value]; shallow[index] = { ...shallow[index], Followers: [{ id: session?.user?.email as string }], _count: { ...shallow[index]._count, Followers: shallow[index]._count?.Followers + 1, }, }; queryClient.setQueryData(["users", "followRecommends"], shallow); } } const value2: User | undefined = queryClient.getQueryData([ "users", userId, ]); if (value2) { const shallow = { ...value2, Followers: [{ userId: session?.user?.email as string }], _count: { ...value2._count, Followers: value2._count?.Followers + 1, }, }; queryClient.setQueryData(["users", userId], shallow); } }, }); console.log("error"); console.dir(error); if (error) { return ( <> <div className={style.header}> <BackButton /> <h3 className={style.headerTitle}>프로필</h3> </div> <div className={style.userZone}> <div className={style.userImage}></div> <div className={style.userName}> <div>@{username}</div> </div> </div> <div style={{ height: 100, alignItems: "center", fontSize: 31, fontWeight: "bold", justifyContent: "center", display: "flex", }} > 계정이 존재하지 않음 </div> </> ); } if (!user) { return null; } const followed = user.Followers?.find((v) => v.id === session?.user?.email); console.log(session?.user?.email, followed); const onFollow: MouseEventHandler<HTMLButtonElement> = (e) => { e.stopPropagation(); e.preventDefault(); console.log("follow", followed, user.id); if (followed) { unfollow.mutate(user.id); } else { follow.mutate(user.id); } }; return ( <> <div className={style.header}> <BackButton /> <h3 className={style.headerTitle}>{user.nickname}</h3> </div> <div className={style.userZone}> <div className={style.userRow}> <div className={style.userImage}> <img src={user.image} alt={user.id} /> </div> <div className={style.userName}> <div>{user.nickname}</div> <div>@{user.id}</div> </div> {user.id !== session?.user?.email && ( <button onClick={onFollow} className={cx(style.followButton, followed && style.followed)} > {followed ? "팔로잉" : "팔로우"} </button> )} </div> <div className={style.userFollower}> <div>{user._count.Followers} 팔로워</div> <div>{user._count.Followings} 팔로우 중</div> </div> </div> </> ); }제가 보기에는 useQuery가 제대로 작동안하는거같은데...제로초님 의견이 궁금합니다팔로우버튼 안눌렀을때 팔로우버튼 눌렀을때
-
미해결Next + React Query로 SNS 서비스 만들기
tailwind
안녕하세요 선생님.요즘 기업 트렌드에 맞게 tailwind로 진행해보려고 하는데강의 css 참고하면서 저 만의 방법으로 tailwind로 수정해서 진행해도 상관없겠죠! 혹시 css로 진행한 이유가 있을까요? 요즘 기업에선 tailwind를 더 추구하나요?저는 tailwind가 더 익숙하더라구요.. 유튜브에서 우연히 제로초 개발자님을 뵙게되어, 제로초의 JS교재와 함께 큰 도움이 되어서 인프런 강의까지 듣게됐네요. 감사합니다!