inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

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

섹션11 [UserModel 생성하기] postgresql Explorer 에서 UserModel 생성문제

미해결

[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core

import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; import { RolesEnum } from '../const/roles.const'; @Entity() export class UserModel { @PrimaryGeneratedColumn() id: number; @Column({ length: 20, unique: true, }) nickname: string; @Column({ unique: true, }) email: string; @Column() password: string; @Column({ enum: Object.values(RolesEnum), default: RolesEnum.USER, }) role: RolesEnum; }

  • javascript
  • typescript
  • rest-api
  • nestjs
  • backend
슈퍼아스라다 댓글 2 좋아요 0 조회수 356

next-auth session expire 관련 질문이 있습니다.

미해결

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

안녕하세요. 우선 강의 너무 잘 보고 있습니다 감사합니다! 강의 내용을 기반으로 NextAuth 관련 작업을 하다가 궁금한 점이 생겼습니다. NextAuth로 signIn 을 할 때 세션 정보가 쿠키에 저장되는데, 이때 max-age 옵션을 따로 설정하지 않으면 기본적으로 1달로 설정되고 있는 것 같습니다. 찾아보니 max-age 값을 최대값으로 설정하려고 해도(예: 4년), NextAuth에서는 자체적으로 최대 1년으로 제한하는 것 같습니다. 여기서 제가 궁금한 것은, NextAuth를 사용하면 쿠키의 max-age 가 최대 1년이고, 그렇다면 1년 후에 세션이 만료되니까 모든 사용자가 로그아웃되는 것인가? 라는 생각이 들었습니다. 세션 저장 기한을 무기한으로 설정하는건 불가능해보이고, 찾아보니 서버 환경에서 세션을 업데이트할 수 있는 unstable_update 라는 함수를 발견했는데 문서에서 해당 함수는 세션 정보를 업데이트하는 것이고 cookie에 저장된 세션 자체의 expire를 조정하는 예시는 나와있지 않아서 이걸 사용하는게 맞는지도 확신이 안드는 상태입니다 ㅠㅠ 지속적으로 접속하는 사용자에 한해서 세션 만료 시간을 연장할 수 있는 방법이 따로 있을까요?

  • next.js
  • next-auth
이자이 댓글 2 좋아요 0 조회수 649

챕터1까지 듣고 질문입니다. 새로고침해도 @modal이 유지되게 할 순 없을까요?

해결됨

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

안녕하세요! 강의 잘듣고있습니다. login 폴더가 불필요한 루트 인 것 같아서 바로 인터셉터 라우터를 이용해 @modal로 연결했습니다. <Link href="/i/flow/login" className={styles.login}>로그인</Link> 또 추가로 새로고침 해도 Modal을 유지하고 싶어서 i/flow/login폴더에서 아래와 같이 마운트시에 인터셉터 하도록 유도하였습니다. "use client"; import { useRouter } from "next/navigation"; import { useEffect } from "react"; export default function Login() { const router = useRouter(); useEffect(() => { router.replace("/i/flow/login"); }, [router]); return null; } 기존 유입방식으로 SSR Page에서 i/flow/login으로 이동 시, 인터셉터 라우팅하여 병렬 라우팅 하던것과 달리, 바로유입 -> i/flow/login -> (replace) -> (.)i/flow/login/page.tsx 순으로 @modal이 출력될줄 알았는데 모달이 출력되질 않네요.. 이유가 i/flow/login으로 바로 접속했기에 상위 폴더 영역에서 {modal}을 선언한 layout을 찾지 못하기 때문에 아무것도 뜨지 않는건가요? 제가 이해한 것이 맞을지 검색해도 잘 안나와서 질문드립니다!

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

eventlistener 질문

미해결

인터랙티브 웹 개발 제대로 시작하기

이벤트 강의를 듣고 나서 addEventListener를 이용하여 여러 장의 사진이 있으면 슬라이더처럼 하나씩 넘겨서 볼 수 있는 이벤트를 만들 수 있을 것 같아 혼자 코드를 직접 짜봤는데요, body 부분은 아래처럼 작성하고, <body> <div class="container"> <div class="slider" id="slider-01"></div> <div class="slider" id="slider-02"></div> <div class="slider" id="slider-03"></div> </div> </body> css는 아래처럼 작성했고, .container { position: relative; width: 660px; height: 440px; overflow: hidden; } .slider { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-size: contain; background-repeat: no-repeat; transform: translateX(100%); } #slider-01 { background-image: url(./images/cat/cat-01.png); z-index: 3; } #slider-02 { background-image: url(./images/cat/cat-02.webp); z-index: 2; } #slider-03 { background-image: url(./images/cat/cat-03.webp); z-index: 1; } .sliderMove { transform: translateX(0%); transition: 1s; } js코드를 아래와 같이 작성했습니다. <script> window.addEventListener("load", function sliderHandler() { const sliderGroup = document.querySelectorAll(".slider"); let currentSlider; function activate(elem) { elem.classList.add("sliderMove"); currentSlider = elem; } function inactivate(elem) { elem.classList.remove("sliderMove"); } for (i = 0; i < sliderGroup.length; i++) { if (currentSlider) { inactivate(currentSlider); } activate(sliderGroup[i]); } }); </script> 후에 실행을 해보니 사진이 슬라이더처럼 작동이 안돼서요.. 작동이 안되는 이유와 어느 부분을 수정해야 하는지 알려주시면 감사하겠습니다! 혹 수업 내용과는 조금 벗어난 질문을 한 거라면 정말 죄송합니다ㅜㅜ..

  • HTML/CSS
  • javascript
  • 인터랙티브-웹
강두희 댓글 1 좋아요 0 조회수 171

정적배포

해결됨

기초부터 배우는 Next YTMusic 클론 코딩 (with next.js 14, UI 마스터)

안녕하세요 ! 강의를 따라하고있다가 문득 생각이 들었는데요. channel / [id] 이렇게 동적 페이지가 나오게 되면 정적 배포를 하게 될땐 어떤 방식으로 하시게 되나요 ?

  • react
  • 인터랙티브-웹
  • 클론코딩
  • next.js
  • tailwind-css
  • zustand
SJ 댓글 1 좋아요 0 조회수 224

안녕하세요, 단위 테스트 대상 관련해서 질문있습니다.

미해결

실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트

web api인 IntersectionObserver을 활용한 훅이 있는데요, 훅은 독립적으로 동작되기 때문에 단위 테스트 대상이라고 말씀하셨는데, 궁금한점은 web api를 활용한 훅은 단위테스트 대상일까요? 테스트 환경이 다르고 web api는 이미 검증된 api이기 때문에 단위테스트 대상에서 제외 했거든요 만약 단위 테스트 대상이라면 web api를 모킹해서 훅을 통해 반환한 값들을 확인 하면될까요? 단위테스트 대상이 아니라면 통합테스트에서 해당 훅을 제대로 호출해서 사용하는지만 확인하면 될까요?

  • javascript
  • react
  • 소프트웨어-테스트
  • vitest
TAEHEE JANG 댓글 1 좋아요 0 조회수 201

frontend 강의 노션 학습 자료가 전혀 보이질 않습니다.

해결됨

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

이렇게 다 사라졌습니다. 다른 학습 자료들은 잘 보이는데 갑자기 왜 frontend학습 자료만 안보이는 걸까요?

  • react
  • node.js
  • seo
  • graphql
  • next.js
akor1 댓글 1 좋아요 1 조회수 175

zustand 상태관리

해결됨

기초부터 배우는 Next YTMusic 클론 코딩 (with next.js 14, UI 마스터)

안녕하세요 ! 강의따라서 zustand 라는 상태관리 지금 사용해보고있는데요 강사님은 현업에서 백엔드와 같이 작업하시면서 zustand 사용하고 계시나요 ?? 만약 사용하고 계신다면 제한사항이나 불편한것들이 있었나요 ??

  • react
  • 인터랙티브-웹
  • 클론코딩
  • next.js
  • tailwind-css
  • zustand
SJ 댓글 1 좋아요 0 조회수 363

감정일기장에서 일기추가와 정렬기능이 되지않습니다.

해결됨

한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

https://github.com/heeyoung123/OneBite 안녕하세요 감정일기장 부분에서 문제가 2가지 생겨서 질문 남깁니다. 일기 작성 후 리스트에 렌더링이 되지않습니다.임시일기데이터에서 정렬을 최신순,오래된순을 바꿔도 적용이 안됩니다.무엇이 문제일까요..

  • javascript
  • react
  • node.js
댓글 2 좋아요 0 조회수 231

state에서 buffer랑 time이 안 나옵니다

해결됨

기초부터 배우는 Next YTMusic 클론 코딩 (with next.js 14, UI 마스터)

예시 코드 따라하는데 재생버튼이 계속 안 나오고 로딩바만 돌아가서 state를 찍어보니까 buffer랑 time 값이 저렇게 빈 값으로 나옵니다. 그런데 isLoading으로 로딩스피너 구현하는 걸 제거하고 바로 play, pause버튼 나오게 하면 노래 자체는 재생이 됩니다만 여전히 buffered와 time 부분 값은 빈 값으로 찍힙니다ㅜㅜ 무엇이 문제일까 모르겠습니다... 코드는 몇번이고 똑같은 걸 검토했는데...

  • react
  • 인터랙티브-웹
  • 클론코딩
  • next.js
  • tailwind-css
  • zustand
gksdygks2124 댓글 2 좋아요 0 조회수 231

안녕하세요 공부 방식에 대해 질문드립니다.

해결됨

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

현재 18강까지 강의를 들었습니다. 수업 방식이 굉장히 효율적이고 짜임새가 있어 독학하기 굉장히 좋다는 느낌을 많이 받았습니다. 근데 저의 공부 방식이 효율적인지 비효율적인지 이 글을 보고 코드캠프 측의 견해를 알려주시면 좋겠다는 생각을 들어 글을 남겨봅니다. 현재 저의 방식은 이렇습니다. ex) 섹션 17, 18강을 듣는다 -> 개념을 노션에 정리하고 이해한다 -> 퀴즈와 포트폴리오를 될 수 있으면 하루에 한개씩 푼다 -> 다 풀기 전에 다음 섹션의 강의를 듣는다 .입니다. 그런데 한 차례의 섹션을 듣고 퀴즈와 포트폴리오를 모두 클리어하고 다음 강의를 듣는게 맞는지, 아님 저처럼 미리미리 들어놓고 다시 한번 재복습 느낌으로 그날그날 해당 섹션의 퀴즈와 포트폴리오를 풀면서찾아보는게 맞는건지 의문이 들어 글을 남겨봅니다.

  • react
  • node.js
  • seo
  • graphql
  • next.js
로그 댓글 1 좋아요 1 조회수 202

반복문 사용 (간단..?)

미해결

자바스크립트 알고리즘 문제풀이 입문(코딩테스트 대비)

const solve = (a,b) => { let left = 0, right = 0 const n = a.length + b.length; const answer = []; for (let i = 0; i < n; i++) { if (a[left] < b[right]) { answer.push(a[left]); left ++ } else { answer.push(b[right]) right ++ } } console.log(answer) } const a = [1,3,5]; const b = [2,3,6,7,9] console.log(solve(a,b)); 반례가 있을까요?

  • javascript
  • 코딩-테스트
hollis9797 댓글 2 좋아요 0 조회수 235

components 들은 jsx 로 만드신 이유

해결됨

기초부터 배우는 Next YTMusic 클론 코딩 (with next.js 14, UI 마스터)

제목과 같이 componets 들에 Sidebar , Header 등은 tsx 로 하지않고 jsx 로 하신 이유가 있나요 ?? ㅎ

  • react
  • 인터랙티브-웹
  • 클론코딩
  • next.js
  • tailwind-css
  • zustand
SJ 댓글 3 좋아요 0 조회수 347

팔로우 게시글 불러올 때 내 게시글이 가져와지는 문제

해결됨

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

getFollowingPosts 호출 시 내 게시글들이 불러와집니다. credentials: 'include' 제대로 넣어줬는데 원인을 모르겠습니다. 무한스크롤은 적용했고 팔로잉은 아직 없는 상태입니다. getFollowingPosts type Props = { pageParam?: number; }; export async function getFollowingPosts({ pageParam }: Props) { const response = await fetch( `${process.env.NEXT_PUBLIC_BASE_URL}/api/posts/followings?cursor=${pageParam}`, { next: { tags: ['posts', 'followings'], }, credentials: 'include', cache: 'no-store', }, ); if (!response.ok) { throw new Error('Failed to fetch data'); } return response.json(); } FollowingPosts 'use client'; import { InfiniteData, useInfiniteQuery } from '@tanstack/react-query'; import { getFollowingPosts } from '../_lib/getFollowingPosts'; import Post from '../../_components/post'; import type { Post as IPost } from '@/model/post'; import { useInView } from 'react-intersection-observer'; import { Fragment, useEffect } from 'react'; export default function FollowingPosts() { const { data, fetchNextPage, hasNextPage, isFetching } = useInfiniteQuery< IPost[], Object, InfiniteData<IPost[]>, [_1: string, _2: string], number >({ queryKey: ['posts', 'followings'], queryFn: getFollowingPosts, initialPageParam: 0, // required getNextPageParam: (lastPage) => lastPage.at(-1)?.postId, // required staleTime: 60 * 1000, gcTime: 300 * 1000, }); const { ref, inView } = useInView({ threshold: 0, delay: 0, }); useEffect(() => { //. inView: ref가 화면에 보일 때 //. !isFetching: 패칭상태 아닐때 (중복 패칭 방지) //. hasNextPage: 다음 페이지가 있을 때 console.log('useEffect', { inView, isFetching, hasNextPage }); if (inView && !isFetching && hasNextPage) { fetchNextPage(); } }, [inView, isFetching, hasNextPage, fetchNextPage]); return data?.pages.map((page, index) => ( <Fragment key={`posts-followings-page-${index}`}> {page.map((post) => ( <Post key={post.postId} post={post} /> ))} {!isFetching && <div ref={ref} style={{ height: 50 }}></div>} {isFetching && <div style={{ height: 50 }}></div>} </Fragment> )); } response에는 내 게시글들이 담겨옵니다 서버쪽 PostsService findAll 콘솔 찍어보면 유저정보 제대로 받아옵니다 { cursor: 0, type: 'followings', user: { id: 'asdf', nickname: '슈퍼맨', image: '/upload/dummy1719568724038.png' } }

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

유저정보 유지관련해서 세션쿠키, 엑세스토큰 질문드립니다.

미해결

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

안녕하세요 선생님 선생님강의 따라서 로그인을 구현했습니다. auth에서 관리해주는 세션으로는 프론트용, 로그인 후 내려주는 connect.id 세션으로는 백엔드용, 으로 사용했습니다. 그런데 궁금한게 로그인을 하고 기간이 지나거나 그런 경우를 대비해서 엑세스토큰, 리프레시 토큰을 많이 사용하는 것을 보았는데 선생님은 넥스트에서 어떤 방식을 사용하시는지, 어떤방식을 추천하시는지 궁금합니다. 검색해보니까 엑세스토큰이 아닌 쿠키세션으로 사용할때에는 일정시간 inter시켜주고 특정시간지나면 쿠키시간을 업데이트해주기도 하더라구요. 선생님 조언이 궁금합니다. 감사합니다.

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

Cannot return null for non-nullable field ~~~ 에러

미해결

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

위와 같이 작성하여 요청하였을 때 이러한 에러가 나타납니다 무엇이 문제일까요?

  • react
  • node.js
  • seo
  • graphql
  • next.js
박진성 댓글 1 좋아요 0 조회수 270

[섹션7-3: 버그수정 2] tempYOffset 오류

미해결

애플 웹사이트 인터랙션 클론!

tempYOffset을 통해서 스크롤 위치를 저장하고 있다가 총 100px을 이동하는 것으로 이해하였는데요. tempYOffset의 초기값, 즉 yOffset이 0으로 출력됩니다. 이게 바로 밑에 있는 window.addEventListener('scroll', () => { } 가 아직 실행되지 않아서 yOffset이 초기화 되지 않아 0으로 나오나? 라고 생각하였는데 막상 강의 코드는 딱히 그런 것을 고려하지 않고도 잘 나오는 것 같더라구요. 혹시 어떤 문제일지 알 수 있을까요? 일단 당장에는 window.scrollY를 사용해서 임시조치로 해결했습니다. // 새로고침 등으로 스크롤을 처음부터 하지 않는 경우 시작하는 경우 해결을 위해 window.addEventListener('load', () => { setLayout(); sceneInfo[0].objs.context.drawImage(sceneInfo[0].objs.videoImages[0], 0, 0); document.body.classList.remove('before-load'); // 특정 위치에서 새로 고침 하면 화면이 나오지 않는 문제를 해결 let tempYOffset = yOffset; let tempScrollCount = 0; // 스크롤 몇 번 했는지 저장 console.log(tempYOffset); console.log(yOffset); let siId = setInterval(() => { window.scrollTo(0, tempYOffset); tempYOffset += 5; tempScrollCount++; if (tempScrollCount > 20) { clearInterval(siId); } }, 20); // ..............

  • HTML/CSS
  • javascript
  • 웹-디자인
  • svg
  • 인터랙티브-웹
  • 클론코딩
신승헌 댓글 1 좋아요 0 조회수 217

3:07에 const result = 입력하는 부분은 복붙인가요??

해결됨

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

플러그인이나 단축키가 따로 있는지 기존에 작성하신 코드 복사 붙여넣기인지 궁금합니다.

  • react
  • 클론코딩
  • next.js
  • supabase
정중한 몽구스 댓글 1 좋아요 0 조회수 192

안녕하세요 배포관련 질문드립니다 !

해결됨

한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지

안녕하세요 배포를 마쳐서 이런식으로 떠서 Production 링크를 누르면 저는 잘 들어가지는데 이 링크를 공유를 하면 다른사람들은 Vercel에 로그인을 하라는 창이 뜨더라고요,,, 어떤 해결방안이 있을까요,,,

  • javascript
  • react
  • node.js
kjklovekhw 댓글 1 좋아요 0 조회수 259

채팅 구현했는데 소켓 연결이 됐다 안됐다 늦게 됐다 합니다.

해결됨

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

안녕하세요 선생님 강의를 보고 참고해서 채팅 기능을 만들었습니다. 그런데 a,b가 채팅화면에 들어왔을때 소켓 연결이 안되거나, 늦게 되거나 하는 경우가 있어서 제가 로직을 잘못짠건지 어딜 확인해야하는건지 조언을 들을수 있을까해서 문의 남깁니다. 먼저 서버에서 이렇게 socket.io 를 설정해주고 /app.js const app = express(); const httpServer = new createServer(app); const io = new Server(httpServer, { cors: { origin: 'https://zzimzzim.com', credentials: true, }, }); /utils/io.js module.exports = function (io, db) { const userSockets = {}; const nsp = io.of('/messages'); nsp.on('connection', (socket) => { console.log('soket connected'); socket.on('disconnect', () => { console.log('-----------------user disconnected'); }); socket.on('login', (user) => { userSockets[user.id] = socket.id; console.log(userSockets, '-------------------------------userSockets'); console.log(`User ${user.id} connected with socket id ${socket.id} --------- 유저입장`); }) socket.on('sendMessage', async (data) => { try { const roomId = data.room.split('-').sort().join('-'); console.log(roomId, '---------------------------------roomId'); console.log(data, '---------------------------------data'); console.log(userSockets, '---------------------------------userSockets'); let room = await db.Room.findOne({ where: { room: roomId }, include: [ { model: db.User, as: 'RoomSender', attributes: ['id', 'email', 'gender', 'mbti'], include: [{model: db.Image}], }, { model: db.User, as: 'RoomReceiver', attributes: ['id', 'email', 'gender', 'mbti'], include: [{model: db.Image}] }, ] }); if (room) { room = await room.update({ content: data.content }); } else { const roomCreated = await db.Room.create({ SenderId: data.senderId, ReceiverId: data.receiverId, content: data.content, room: roomId, }) console.log(roomCreated, '------------------------------roomCreated') room = await db.Room.findOne({ where: { room: roomId }, include: [ { model: db.User, as: 'RoomSender', attributes: ['id', 'email', 'gender', 'mbti'], include: [{model: db.Image}], }, { model: db.User, as: 'RoomReceiver', attributes: ['id', 'email', 'gender', 'mbti'], include: [{model: db.Image}] }, ] }) } const savedMessage = await db.Message.create({ SenderId: data.senderId, ReceiverId: data.receiverId, content: data.content, room: roomId, }); // console.log(savedMessage, '------------------------Message saved'); console.log(room, '------------------------room saved'); const receiverSocketId = userSockets[data.receiverId]; if (receiverSocketId) { socket.to(receiverSocketId).emit('receiveMessage', savedMessage); socket.to(receiverSocketId).emit('receiveRoom', room); } else { console.log(`User ${data.receiverId} is not connected`); } } catch (error) { console.error('Error saving message:', error); } }); }) } 클라이언트에서는 선생님이 useSocket만든것과는 다르게 useContext를 이용해서 /src/app/(afterLogin)/messages/_component/SocketProvider.tsx 'use client'; import { useSession } from 'next-auth/react'; import { ReactNode, createContext, useCallback, useEffect, useMemo, useState } from 'react'; import { io, Socket } from 'socket.io-client'; type Props = { children: ReactNode }; type SocketContextType = { socket: Socket | null; isConnected: boolean; disconnect: Function; goDown: boolean; setGoDown: Function; } export const SocketContext = createContext<SocketContextType>({ socket: null, isConnected: false, disconnect: () => { }, goDown: false, setGoDown: () => {}, }) export default function SocketProvider({ children }: Props) { const { data: session } = useSession(); const [socket, setSocket] = useState<any | null>(null); const [isConnected, setIsConnected] = useState(false); const [goDown, setGoDown] = useState(false); const disconnect = useCallback(() => { socket?.disconnect(); setSocket(null); }, [socket]); const value = useMemo(() => { return { socket, isConnected, disconnect, goDown, setGoDown } }, [socket, isConnected, disconnect, goDown]); useEffect(() => { console.log(socket, '-----------------------------------------socket???'); if (!socket) { const socketInstance = io(`${process.env.NEXT_PUBLIC_BASE_URL}/messages`, { withCredentials: true, }); socketInstance.on('connect', async () => { setIsConnected(true); console.log("소켓연결 성공!!!", socketInstance.id); // console.log(socketInstance, '--------------------socketInstance'); }) setSocket(socketInstance); } }, [socket]); useEffect(() => { if (socket?.connected && session?.user?.id) { console.log('--------------------------------------------socket emit login') socket?.emit('login', { id: session?.user?.id }); } }, [session, socket]); return ( <SocketContext.Provider value={value}> {children} </SocketContext.Provider> ) } 이런식으로 만들고 /src/app/(afterLogin)/messages/layout.tsx import { ReactNode } from 'react'; import SocketProvider from './_component/SocketProvider'; type Props = { children: ReactNode }; export default function Layout({ children }: Props) { return ( <SocketProvider> {children} </SocketProvider> ) } 레이에다가 적용해주었습니다. 이런식으로 해주면 소켓연결을 한번만 하고 원할때 메세지를 주고 받을 수 있을거라고 생각해서 적용한건데 혹시 소켓 연결 관련해서 더 확인해야하거나 수정할 부분이 있을지 궁금합니다. 감사합니다!

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

인기 태그

인프런 TOP Writers

주간 인기글