묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
이 강의는 이제 업데이트가 진행되지 않는건가요?
문의드립니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
새버전 강의
주기적으로 업데이트한다고 강의 소개에 크게 적어놓으셨는데, 왜 2023년 초 이후로 업데이트가 없나요?그리고 새로운 버전 강의가 나왔던데, 이전 버전 수강자들에게는 무료로 제공되나요?이 강의가 저렴한 것도 아니고 몇십만 원이나 하는데, 그 정도 보상은 해주셔야 한다고 생각합니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
신규강의가 비슷하게 나왔던데...
기존에 프론트엔드 강의 수강생들에 대한 혜택은 없는건가요?? 거기는 이제 업데이트 안되는건가요?? 아 너무한데.....
-
해결됨Next + React Query로 SNS 서비스 만들기
리액트 쿼리를 활용한 SSR으로 데이터 조회하기
안녕하세요!제가 강의를 모두 수강하고 프로젝트에서 리액트 쿼리를 통해 SSR을 적용하려고 하고 있습니다. 아래 코드는 fetchAPISever 함수를 통해 백엔드 api로부터 데이터를 요청하는 함수입니다. 이때fetchAPIsever 함수는 next/header의 cookies()를 통해 사용자의 토큰이 있으면 토큰을 넣어서 api를 요청하는 함수입니다.export const getBestAndPendingReviews = async (): Promise<ReviewePageResponse> => { const res = await fetchAPIServer('/api/review', 'GET'); if (res.code === 'SUCCESS') { return res.result; } throw new Error( `리뷰 페이지 데이터 불러오기 실패 ${res.code}-${res.message}`, ); }; 아래 코드는 리뷰 페이지에서 서버 사이드 렌더링으로 보여주기 위해 리액트 쿼리로 Hydration을 적용한 코드입니다.// src\app\reviews\page.tsx import { HydrationBoundary, QueryClient, dehydrate, } from '@tanstack/react-query'; import ReviewDashboard from './_components/ReviewDashboard'; import { getBestAndPendingReviews } from './_lib/getBestAndPendingReviews'; export default async function ReviewsPage() { const queryClient = new QueryClient(); await queryClient.prefetchQuery({ queryKey: ['reviews', 'best'], queryFn: getBestAndPendingReviews, }); const dehydrateState = dehydrate(queryClient); return ( <HydrationBoundary state={dehydrateState}> <ReviewDashboard /> </HydrationBoundary> ); } ' <ReviewDashboard/> 컴포넌트에서 UserInfo 컴포넌트를 반환하도록 설정하고 useQuery 훅을 사용하려 했으나, fetchAPIServer 함수에서 next/headers 를 import하고 있어서 클라이언트 컴포넌트에서 사용할 수 없다는 에러가 발생했습니다. 그러면 SSR을 적용하기 위해서는 getQueryData를 사용해야하는 걸까요..?import { QueryClient } from '@tanstack/react-query'; import { ReviewePageResponse } from '../_lib/getBestAndPendingReviews'; export default function UserInfo() { const queryClient = new QueryClient(); const reviews = queryClient.getQueryData<ReviewePageResponse>([ 'reviews', 'best', ]); const { total } = reviews!; if (!reviews) return <p>리뷰가 없습니다.</p>; console.log('reviews', reviews); return <p>작성한 리뷰 {total || 0}</p>; } 또는 useQuery를 쓰되 쿼리 함수를 Promise.Resolve()로 서버에서 전달 받은 데이터를 받는게 나은가 요? 'use client'; import { useQuery } from '@tanstack/react-query'; export default function UserInfo() { const { data: reviews, isLoading } = useQuery({ queryKey: ['reviews', 'best'], queryFn: () => Promise.resolve(), // 서버 데이터 재활용 }); if (isLoading) return <p>Loading...</p>; if (!reviews) return <p>리뷰가 없습니다.</p>; const { total } = reviews!; console.log('reviews', reviews); return <p>작성한 리뷰 {total || 0}</p>; }
-
미해결Next + React Query로 SNS 서비스 만들기
페러렐 라우트(default.tsx)
강사님 안녕하세요! 강의 수강 후 개인 프로젝트 진행중인데 페러렐 라우트 부분에서 막혀 질문남깁니다ㅜㅠ..default.tsx는 강의에서 진행해주신대로 return null;을 넣었습니다. (.next 캐쉬도 지웠습니다)// 폴더구조 app/ ├──(afterLogin) │ ├── _component │ │ ├── Header.tsx // header 컴포넌트 │ ├── @message │ │ ├── page.tsx │ │ ├── default.tsx │ ├── @modal │ │ ├── //...compose/[username] 등 폴더 │ │ ├── default.tsx │ ├── home │ │ ├── page.tsx // home 컴포넌트 │ ├── default.tsx │ ├── layout.tsx │ │ ├──(beforeLogin) │ ├── page.tsx │ ├── layout.tsx ├── layout.tsx // (afterLogin)/layout.tsx import { ReactNode } from "react"; import Header from '@/app/(afterLogin)/_component/Header'; type Props = {children: ReactNode, modal: ReactNode, message: ReactNode;}; export default function AfterLoginLayout({children,modal,message,}: Props) { return ( <div className="wrap"> <Header /> <div className="container">{children}</div> <div className="chatting">{message}</div> {modal} </div> ); }해당 이미지와 같이 layout에서 header/{children}/{message}/{modal}을 띄우고 싶은데 message부분이 나오고 있지 않습니다..! (그래서 afterLogin의 layout.tsx와 같은 상위요소에 default를 만들어도 똑같더라구요..)<질문>1. 제가 폴더구조를 잘못 짠 걸까요..?2. (afterLogin)/@message/default.tsx(default.tsx에서 @message/page.tsx를 import해서 진행해도 될까요? 요런식으로 하면 잘 노출이 됩니다..!)import Message from './page'; export default function Default() { return <Message /> }3. 아니면 header처럼 컴포넌트 형식으로 메시지창만 만든다음 onClick되면 -> 인터셉팅으로 가로채는것(/message/page.tsx)이 좋을까요?조언 부탁드리겠습니다..!! ĭ˄ĭ
-
미해결Next + React Query로 SNS 서비스 만들기
RequestMemoization 관련해서 질문드립니당
데이터 캐시 설정을 force-cache 로 했을 때 이걸 갱신하기 위한 방법으로 revalidate 옵션을 주거나 revalidateTag, revalidatePath 등이 있다고 하셨는데요.그러면 RequestMemoization에 의해서 캐싱된 데이터는 브라우저 새로고침 등을 하면 다시 fetch 하면서 갱신이 되는건가요?RequestMemoization 에 의해서 캐싱된 데이터는 언제 갱신되는지 궁금합니다. 그런데 제가 이해한 바로는 유저가 처음 브라우저를 통해 애플리케이션에 접근해서 해당 url 에서 요청을 보냈을 때 특정 데이터를 페칭하는 함수가 여러 컴포넌트에 있어서 그 데이터를 불러오기 위한 요청을 한 번만 함으로써 서버에 요청이 가는 것을 줄여주는것이 RequestMemoization 이라고 저는 이해를 했는데요. 어차피 처음에 같은 데이터를 보여주기 위해 여러 번의 요청을 하는 것은 불필요한 네트워크를 타게 되고 성능상에 좋지 않으니까요.이런 경우라면 사실 RequestMemoization 은 캐싱된 데이터를 갱신할 필요가 없을 수도 있겠다는 생각이 듭니다.그래서 제로초님이 별다른 언급이 없으셨나? 하는 생각도 드네요. 감사합니다.
-
미해결Next + React Query로 SNS 서비스 만들기
next.js 15 로 진행 중인데 리액트 쿼리 설치 관련 질문입니다.
next.js 15 로 따라가면서 진행 중인데 리액트 쿼리를 설치하려고 하니 리액트19 가 아직 안정적이지 않아서 npm 설치할 때 충돌이 생긴다고 에러가 뜨는 것 같습니다.npm ERR! code ERESOLVEnpm ERR! ERESOLVE unable to resolve dependency treenpm ERR!npm ERR! While resolving: z-com@0.1.0npm ERR! Found: react@19.0.0-rc-66855b96-20241106npm ERR! node_modules/reactnpm ERR! react@"19.0.0-rc-66855b96-20241106" from the root projectnpm ERR!npm ERR! Could not resolve dependency:npm ERR! peer react@"^18 || ^19" from @tanstack/react-query@5.62.7npm ERR! node_modules/@tanstack/react-querynpm ERR! @tanstack/react-query@"*" from the root projectnpm ERR!npm ERR! Fix the upstream dependency conflict, or retrynpm ERR! this command with --force or --legacy-peer-depsnpm ERR! to accept an incorrect (and potentially broken) dependency resolution.-------리액트 19 안정화 버전으로 업데이트 진행했습니다! 그랬더니 next 와 리액트19 사이에 에러가 발생해서 next 도 latest 로 업데이트 해주고 리액트 쿼리를 설치하니까 되네요!이 방법이 맞는지는 모르겠지만 일단 이렇게도 되긴 합니다!
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
날씨 API 코드 오류
const weatherSearch = function (position) { console.log(position); fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${position.latitude}&lon=${position.longitude}&appid=9756434244216c3d2f9c08591b54bede`) } // 위치 정보를 처리하는 함수 const acessToGeo = function (position) { const positionObj = { latitude: position.coords.latitude, // 위도 longitube: position.coords.longitude // 경도 (오타: longitube → longitude) }; console.log(positionObj); // 위치 정보 출력 console.log(position); // 전체 위치 데이터 출력 weatherSearch(positionObj) }; 2.5로 수정햇는데 오류가 뜨네요 어떠한 오류인 지 모르겠습니다 밑 코드는 // DOM 요소 선택 const todoInput = document.querySelector("#todo-input"); // 할 일 입력 필드 const todoList = document.querySelector("#todo-list"); // 할 일 목록 // localStorage에서 저장된 데이터를 불러오기 const savedTodoList = JSON.parse( localStorage.getItem("saved-items") ); /* 문자열로 저장된 데이터를 JSON.parse를 통해 배열로 변환 */ // 새로운 할 일을 생성하는 함수 const createTodo = function (storageData) { let todoContents = todoInput.value; // 입력 필드에서 가져온 값 if (storageData) { todoContents = storageData.contents; // 저장된 데이터가 있으면 그 내용을 사용 } // 할 일을 나타내는 DOM 요소 생성 const newLi = document.createElement("li"); // li 요소 생성 const newSpan = document.createElement("span"); // span 요소 생성 (할 일 내용 표시) const newBtn = document.createElement("button"); // 완료 버튼 생성 // 완료 버튼 클릭 시 해당 할 일을 완료 상태로 변경 newBtn.addEventListener("click", () => { newLi.classList.toggle("complete"); // 완료된 상태를 토글 saveItemsFn(); // 변경 내용을 저장 }); // 할 일을 더블클릭하면 삭제 newLi.addEventListener("dblclick", () => { newLi.remove(); // li 요소 제거 saveItemsFn(); // 변경 내용을 저장 }); // 저장된 데이터가 완료 상태면 완료 표시 추가 if (storageData?.complete) { // 옵셔널 체이닝 사용 newLi.classList.add("complete"); // 완료 클래스 추가 } // 할 일 내용을 span에 추가 newSpan.textContent = todoContents; // li 요소에 버튼과 span을 자식으로 추가 newLi.appendChild(newBtn); newLi.appendChild(newSpan); // 할 일 목록에 li 추가 todoList.appendChild(newLi); // 입력 필드를 비우기 todoContents.value = ""; // 변경된 목록 저장 saveItemsFn(); }; // Enter 키를 눌렀을 때 할 일 추가 const keyCodeCheck = function () { if (window.event.keyCode === 13 && todoInput.value !== "") { createTodo(); // 입력값이 있으면 할 일을 생성 } }; // 전체 삭제 기능 const deleteAll = function () { const liList = document.querySelectorAll("li"); // 모든 li 요소 선택 for (let i = 0; i < liList.length; i++) { liList[i].remove(); // 모든 할 일 제거 } saveItemsFn(); // 변경 사항 저장 }; // localStorage에 저장하는 함수 const saveItemsFn = function () { const saveItems = []; // 저장할 데이터를 담을 배열 // 현재 목록의 할 일들을 객체로 변환하여 저장 for (let i = 0; i < todoList.children.length; i++) { const todoObj = { contents: todoList.children[i].querySelector("span").textContent, // 할 일 내용 complete: todoList.children[i].classList.contains("complete"), // 완료 상태 }; saveItems.push(todoObj); // 객체를 배열에 추가 } // 배열이 비었으면 localStorage에서 데이터 제거, 아니면 저장 saveItems.length === 0 ? localStorage.removeItem("saved-items") // 데이터가 없으면 키 삭제 : localStorage.setItem( "saved-items", JSON.stringify(saveItems) // 배열을 문자열로 변환 후 저장 ); }; // 저장된 데이터가 있으면 불러와 화면에 표시 if (savedTodoList) { for (let i = 0; i < savedTodoList.length; i++) { createTodo(savedTodoList[i]); // 저장된 데이터로 할 일을 생성 } } const weatherSearch = function (position) { console.log(position); fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${position.latitude}&lon=${position.longitude}&appid=9756434244216c3d2f9c08591b54bede`) } // 위치 정보를 처리하는 함수 const acessToGeo = function (position) { const positionObj = { latitude: position.coords.latitude, // 위도 longitube: position.coords.longitude // 경도 (오타: longitube → longitude) }; console.log(positionObj); // 위치 정보 출력 console.log(position); // 전체 위치 데이터 출력 weatherSearch(positionObj) }; // Geolocation API로 사용자 위치 요청 const askForLocation = function () { navigator.geolocation.getCurrentPosition( acessToGeo, // 위치 정보를 가져오면 실행할 콜백 (err) => { console.log(err); // 에러가 발생하면 에러 정보를 출력 } ); }; // 위치 요청 실행 askForLocation();
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
fetch() 사용 관련 질문입니다.
안녕하세요.강의를 전부 수강한 수강생입니다. 강사님의 강의를 보다가 궁금한 것이 있어서 질문 남깁니다. 강의에서는 API 요청 방식을 fetch를 사용하여 전부 Next 서버에서 요청을 보내는 방식이던데 클라이언트 컴포넌트에서 fetch를 사용하여 브라우저를 통해 요청하는 방법과 강의와 같이 사용하는 방법, API Route(Handle) 방식을 사용하는 방법의 차이를 알 수 있을까요?? 또한 Next 서버의 부하는 괜찮은지 궁금합니다.
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
데이터베이스 초기화(npx prisma db push) 이슈입니다.
npm install 해서 의존성 설치후에 npx prisma db push를 했는데$ npx prisma db pushEnvironment variables loaded from .envPrisma schema loaded from prisma\schema.prismaDatasource "db": PostgreSQL database "postgres", schema "public" at "aws-0-ap-northeast-2.pooler.supabase.com:5432"Error: P1001: Can't reach database server at aws-0-ap-northeast-2.pooler.supabase.com:5432Please make sure your database server is running at aws-0-ap-northeast-2.pooler.supabase.com:5432.이렇게 나옵니다. 챗지피티랑 스택 오버플로우 이런거 봐도 잘 안돼서 질문드립니다.
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
CSR, SSR 렌더링 방식 문의
안녕하세요~설명해주신 CSR, SSR 렌더링 강의보고 CSR, SSR 렌더링 방식에 대해 궁금한점 두가지 남겨봅니다!(유사한 질문이 있는지 찾아봤는데 글이 많아서 찾질 못해서 중복 감안하고 올려봅니다🙏🏻) 질문1CSR은 bundle js 다운로드 레이턴시 만큼 FCP가 느리고 반대로 SSR은 bundle js 다운로드 레이턴시만큼 CSR보다 FCP가 빠르다고 이해했는데요. TTI 기준으로 보면 결국 CSR, SSR모두 차이가 없는게 맞을까요? (gzip압축 해제, js parse, hydration등의 처리에서 드는 비용의 차이가 있겠지만 이런 부분들은 크게 영향을 주진 않을거라고 생각하여 문의드립니다. 혹시 두 방식에 영향을 미치는 큰 요소가 있다면 그 부분도 고려해서 알려주시면 감사하겠습니다.) 질문2CSR의 장점으로 초기 렌더링이 느리고 이후에 페이지 이동시 빠르게 화면을 그릴 수 있다고 하셨는데요, CSR에서 초기 렌더링의 속도를 높이기 위해 코드 스플리팅 전략을 취할 수 있을거 같습니다. 이렇게 CSR에서 코드 스플리팅 방식을 취한 경우 페이지 이동시 결국 bundle js 다운르드 레이턴시가 또 발생할거 같은데요. prefetch, preload같은 전략을 취하지 않고 코드스플리팅만 적용한 CSR방식은 단점만 남는 렌더링 전략이 맞을까요? 유일한 장점은 CSR이지만 코드 스플리팅을 했기 때문에 초기 FCP가 조금 빠르다정도일거 같은데 이해한게 맞는지 문의드려봅니다.
-
미해결Next + React Query로 SNS 서비스 만들기
Next-Auth 관련해서 질문이 있습니다.
백엔드 취준생인데 프론트를 좀 할 일이 있어서 강의 듣고 있는데 Next-Auth 부분이 이해가 쉽지 않네요... 몇 가지 질문 드리고자 합니다.1. session 객체에 어떤게 담기는건지 잘 모르겠습니다.export default async function Home() { const session = await auth() if (session?.user) { redirect('/home') return null } return ( <Main/> ); }export const { handlers: { GET, POST }, auth, signIn, } = NextAuth({ // 개발자가 직접 만든 화면에서 로그인 하도록 진행 pages: { signIn: '/i/flow/login', // 로그인 newUser: '/i/flow/signup' // 회원가입 }, providers: [ CredentialsProvider({ async authorize(credentials) { const authResponse = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/login`, { method: 'POST', headers: { "Content-Type": "application/json", }, body: JSON.stringify({ id: credentials.usename, password: credentials.password, }) }) if (!authResponse.ok) { return null } const user = await authResponse.json() return { email: user.id, name: user.nickname, image: user.image, ...user } } }) ], })Home 에서 auth() 를 통해 불러온 session 객체에 CredentialsProvider 가 리턴한 객체가 담기는건가요?그런데 그렇다고 하기엔 객체에 user 라는 속성이 없어서 아닌 것 같기도 해서 아닌 거 같다는 생각도 듭니다. export default function Login() { const router = useRouter() const { data: session } = useSession(); if (session?.user) { router.replace('/home') return null } router.replace("/i/flow/login") return ( <Main /> ) }마찬가지로 여기서도 session 에 어떤게 담기는지 잘 모르겠습니다 ㅠㅠ auth() 로 리턴한 세션과 같은 객체가 담기는 것 같긴 한데 도대체 session 에 뭐가 담기는지 파악이 쉽지 않네요 ㅋㅋㅋ그래서 session 객체의 user 를 클릭해서 들어가보니 다음과 같은 interface 가 나오네요.export interface DefaultSession { user?: User expires: ISODateString }auth/core 에 있는 인터페이스인 것 같은데 이 인터페이스가 어느 시점에 등장(?) 하는 건지 잘 모르겠습니다.2. 지금 진행하는 로그인 방식은 백엔드에 로그인 관련 API 가 있다고 가정하고 진행하는 것으로 저는 이해를 했는데요export const handlers = [ http.post(`${baseUrl}/api/login`, () => { console.log('로그인'); return HttpResponse.json(User[1], { headers: { 'Set-Cookie': 'connect.sid=msw-cookie;HttpOnly;Path=/' }, }) }), http.post(`${baseUrl}/api/logout`, () => { console.log('로그아웃'); return new HttpResponse(null, { headers: { 'Set-Cookie': 'connect.sid=;HttpOnly;Path=/;Max-Age=0' } }) }), http.post(`${baseUrl}/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=/' }, }); }) ];이게 지금 api 를 mocking 한 건데 여기에 요청을 보내고 있으니까요.그러면 이 API 에서 리턴한 유저(User[1]) 가 세션에 담기는 것인지 궁금하네요. (이것도 1번 질문하고 좀 연관이 되네요) 그러면 만약에 백엔드 API 가 로그인 성공했을 때 http body 에 별도의 객체를 리턴하지 않으면 어떻게 되나? 이런 궁금증도 생깁니다.3. 그리고 로그아웃을 할 때는 왜 로그아웃 API 에 따로 요청을 보내지 않고 signOut 함수만 사용하는지 궁금합니다. 이것만 사용해도 쿠키가 삭제가 돼서 그런 것인가요? 그러면 백엔드 서버에 별도의 로그아웃 API 를 만들지 않아도 되는 것인지 궁금합니다. 장문의 질문글이 된 거 같은데, 뭔가 Next-Auth 를 처음 접하다보니 사용법이 좀 익숙치가 않네요. AI 에 물어보거나 구글링을 해 봐도 좀 파악이 쉽지 않아 여기에 질문 남겨봅니다.감사합니다.
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
ES Lint 9에서의 rule 설정
ES Lint 설정안녕하세요. 현재 Next.js 15.1 버전에서ESLint가 9버전으로 업데이트 되면서 형식이 많이 바뀌었는데 기존의 8 버전에서는{ "extends": ["next/core-web-vitals", "next/typescript"], "rules": { "@typescript-eslint/no-unused-vars": "warn", "@typescript-eslint/no-explicit-any": "off" } } 하지만 9 버전에서는 형식이 많이 바뀌었는데no-unused-vars나 on-explicit-any 같은 설정은 어떻게 해야 하나요? 일단은 이렇게 코드를 쓰기는 했는데 적용이 잘 안되는 것 같습니다.(eslint.config.mjs)import { dirname } from "path"; import { fileURLToPath } from "url"; import { FlatCompat } from "@eslint/eslintrc"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const compat = new FlatCompat({ baseDirectory: __dirname, }); export default [ ...compat.extends("next/core-web-vitals", "next/typescript"), { files: ["**/*.ts", "**/*.tsx"], rules: { "@typescript-eslint/no-unused-vars": "off", "@typescript-eslint/no-explicit-any": "warn", // 경고로 설정 }, }, ];
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
클라이언트 컴포넌트의 사전 렌더링 질문
안녕하세요, 우선 강의 너무 잘 들었습니다.사전 렌더링에 대한 부분에서 궁금중이 있어 문의를 남깁니다. 클라이언트 컴포넌트 또한 서버에서 JS 실행을 통해 서버 측에서 사전 렌더링이 된다는 것을 알고 있습니다.다만, 서버에서 실행되는 사전 사이드 렌더링의 경우 useEffect, useState 등과 같은 훅은 어떤 식으로 실행이 되는지 궁금합니다. 왜냐하면 서버 클라이언트에서는 훅 사용이 불가능한 것으로 알고 있는데, 이는 곧 서버에서 훅을 사용하지 못한다는 뜻으로 이해하고 있어서요.만약 해당 훅 들이 서버에서 실행되지 않고, 컴포넌트에 마운트 된 이후에 실행 되는 것이라면, 컴포넌트 return 문 안에 있는 State나 로직들은 undefined 인 상태에서 렌더링 되어 Client에 HTML 형태로 전달 되는 것일까요? 또한 비슷한 질문인데, 사전 렌더링에서 local storage, DOM 조작 등과 같이 Client에서만 접근 가능한 API에서는 어떤 식으로 사전 렌더링이 진행되는지, 그리고 초기 HTML을 그릴 때는 해당 값들을 어떻게 처리하는 지 궁금합니다. 좋은 강의 감사합니다!
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
서버 액션을 트리거하는 방법
안녕하세요.지금까지 서버 액션을 트리거 하실때 form 태그를 이용해서, 제출형식으로 트리거 하셨는데, next 에서 서버 액션을 트리거 할때 단순한 작업이라면 form태그가 아닌 버튼형식으로 하는것도 괜찮은지 궁금해서 여쭤봅니다. 버튼으로 하는것도 가능은 하지만 권장되지 않는 방식인것인가요?이를테면 각각의 북페이지에 유저가 좋아요와 싫어요를 누를 수 있는 기능이 있다고 가정했을때, 좋아요와 싫어요는 단순한 기능이라고 생각이 되는데, 이런 경우에는 버튼으로 서버 액션을 트리거하는 방법도 괜찮은것인지 궁금합니다!. 감사합니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
/boards/224/ 403 이 뜨네요.
next.config.mjs/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, trailingSlash: true, generateBuildId: () => "tranme24", // 아래 주소들만 out 폴더에 만들기 exportPathMap: () => ({ "/": {page: "/"}, "/boards": {page: "/boards"}, "/404": {page: "/404"}, }) }; export default nextConfig; 위와같이 설정 경로에서 아래의 이미지와 같이 파일들이 동일한걸 확인했습니다.왜 안되는걸까요.
-
미해결Next + React Query로 SNS 서비스 만들기
안녕하세요! next-auth 로그인하기 부분 질문입니다.
지금 강의에서 보여주신게 아직 업데이트가 안 된 것인지 궁금합니다!Auth.js 홈페이지에 있는 문서와 코드가 조금 다른 것 같아서요. next.js 15 버전으로 강의 따라가고 있고 auth.js 설치할 때 auth@5 하니까 설치가 안 돼서 auth@beta 이렇게 설치하고 진행 중 입니다! 제가 본 페이지는 다음과 같습니다.https://authjs.dev/getting-started/authentication/credentials 추가일단 제로초님이 하신 방법으로 CredentialsProvider 직접 import 하니까 되는 것 같습니다!
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
사용중인 Theme 문의
안녕하세요, 강사님. 강의 너무 잘 듣고 있습니다. 혹시 사용중이신 Theme과 어떻게 설정하고 있는지 공유 부탁드려도 될까요? 가독성이 좋아서 저도 동일하게 적용하고 싶습니다. 감사합니다.
-
미해결따라하며 배우는 리액트 A-Z[19버전 반영]
useEffect로 사용을 해도 되나요?
useEffect(() => { localStorage.setItem('todoData', JSON.stringify(todoData)); }, [todoData]); 이렇게 작성을 하고, 나머지는 다 주석을 처리했는데도 정상 작동하는 것 같더라구요. 하지만 의문인게 setTodoData((prev) => [...prev, newTodo]); localStorage.setItem('todoData', JSON.stringify([...todoData, newTodo]));여기도 주석처리를 했는데, 여기는 조금 작성하는 게 다르지 않나요? handleRemoveClick = () => { setTodoData([]) }여기도 그렇구요. 그런데 그냥 다 정상 작동 하네요?
-
미해결Next + React Query로 SNS 서비스 만들기
로그인 방식 관련해서 질문드립니다!!
로그인 방식을 구현하면서, 쿠키로만 개발할 경우 완전히 백엔드에 의존하게 되어 로컬로, 동시에 키고 개발을 하지 않는이상, 도메인간 불일치를 해결 할 방법이 없어, msw를 사용해야 한다고, 이전에 말씀해주셨습니다!!보통, 회사나, 개인 소프트웨어를 만들 때 어떤 방식으로 로그인을 주로 만드시는지 조금 알고 싶어 궁금하여 질문을 남깁니다!!로그인 방식 고찰로그인 성공시, accessToken을 body로 받고, refreshToken은, httpOnly 쿠키로 받는 경우 (서버에서, DB or Redis를 통해 refreshToken 관리) → 인증 필요 요청 (Bearer accessToken), 리프레시 필요 요청 (refreshToken 심긴 쿠키를 바탕으로 요청)- DB에서 관리하는 것 보다, redis를 통해 관리했을 떄 읽기 속도가 빠름을 확인!응답: accessToken과 refreshToken 모두 body로 클라이언트에게 전달.인증 필요 요청과, 리프레시 토큰 재발급 요청 모두 헤더의 Bearer에 accessToken이나, refreshToken을 넣어서 전달.)현재 방식: accessToken, refreshToken 모두 쿠키로 응답받고, 요청또한, 쿠키를 포함하여 전달.제로초님은, Next.js를 활용하여, 웹 사이트를 만드실 떄, 어떠한 방식으로 로그인을 구현하시는지 궁금하고, 많은 회사에서 사용하는 방식은 보통 어떤 방식인지도 알고싶습니다!