172만명의 커뮤니티!! 함께 토론해봐요.
미해결
타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게
뒤를 들어보지 않고 남겨서 죄송합니다. 이전 코딩 경험으로는 Todo에 있는 todo리스트와 컴포넌트를 전역변수로 만들어서(static)으로 만들어서 다른 모든 컴포넌트에서 참조하도록 하면 훨씬 쉬울 것이라고 예상되는데요. 리액트로 이러한 구조가 있나요?
react react-router redux-toolkit zustand react.js
양승근
2026-07-30T01:01:54.607Z
댓글 2
좋아요 0
조회수 15
미해결
타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게
checkbox를 커스터마이징 했다는 뜻이 무엇일까요?
react react-router redux-toolkit zustand react.js
양승근
2026-07-29T06:32:48.377Z
댓글 2
좋아요 0
조회수 24
미해결
타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게
몽고 DB 접속 중인데요 강의내용 같이 mongodb+srv://admin:qwe123!!@cluster0.ic4ilij.mongodb.net/react_blog?retryWrites=true&w=majority&appName=Cluster0 하고 Connection whit Conection String "Connect"를 누르면 Unable to connect: querySrv ENOTFOUND mongodb. tcp.cluster0.ic4ilij.mongodb.net 라는 메시지와 함께 접속이 안되고 있습니다. 원인과 해결 방안을 여쭤 봅니다. -- 감사합니다.
react react-router redux-toolkit zustand react.js
bluescreen
2026-07-27T12:55:13.659Z
댓글 2
좋아요 0
조회수 32
해결됨
React 마스터 클래스: Part 3 - 실무 핵심 라이브러리 정복 (TypeScript, Zustand, React Hook Form, TanStack Query)
'81강. [Pain] 대규모 삭제 작업 시 발생하는 수많은 요청을 하나로 묶기' 에 관하여 실습 자료가 없는데 혹시 의도된 것일까요?
javascript react typescript frontend zustand
Yoon Robin
2026-07-23T06:20:21.053Z
댓글 2
좋아요 0
조회수 41
미해결
타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게
제가 못 찾은건지 소스코드는 따로 제공되지 않을까요?
react react-router redux-toolkit zustand react.js
김성욱
2026-07-21T13:43:30.609Z
댓글 2
좋아요 0
조회수 52
해결됨
React 마스터 클래스: Part 3 - 실무 핵심 라이브러리 정복 (TypeScript, Zustand, React Hook Form, TanStack Query)
62강 실습 자료로는 ' [Solution] Stale-While-Revalidate: 사용자에게는 캐시를, 뒤에서는 갱신을' 에 관한 내용이 나와야하는데, 현재는 '[Pain] 수동으로 관리하던 전역 로딩/에러 상태가 로직을 오염시킬 때' 로 나와있습니다. 62강 실습 자료 교체 부탁드립니다.
javascript react typescript frontend zustand
Yoon Robin
2026-07-21T05:06:42.077Z
댓글 1
좋아요 0
조회수 36
미해결
타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게
안녕하세요 일반적으로 project를 생성하면 App.tsx 파일이 존재 하는데요 App.tsx 파일이 존재하지 않는 경우는 어떤 경우일까요? 안에 있는 내용을 다른 파일로 옮기는 건가요? 꼭 App.tsx 파일이 필요없는 것 같은데요 개발자가 만들기 나름인가요?
react react-router redux-toolkit zustand react.js
bluescreen
2026-07-20T05:53:11.381Z
댓글 2
좋아요 0
조회수 52
해결됨
한 입 크기로 잘라먹는 React.js 실전 프로젝트 - SNS 편
안녕하세요 정환님, 이렇게 바로 또 질문을 드릴 줄은 몰랐는데.. 이번 포스트 작성 중 이탈 방지 기능 개발을 하다가 "확인 버튼"을 누르게 되면 정상적으로 모든 모달이 종료가 되지만, "취소 버튼"을 누르게 되면 AlertModal이 종료되지 않고 계속 리렌더링이 되는 현상이 발생합니다ㅠㅠ 해당 부분에 대해 저번처럼 메일로 프로젝트 파일을 압축해서 보내드려도 되는지 여쭤봅니다!
react typescript react-query supabase zustand
rkdla666
2026-07-15T03:35:21.304Z
댓글 2
좋아요 0
조회수 57
해결됨
한 입 크기로 잘라먹는 React.js 실전 프로젝트 - SNS 편
안녕하세요 정환님! 정환님의 강의를 들으면서 코드를 따라 작성해보다가 포스트와 이미지를 최종적으로 업로드 하는 과정에서 아래의 캡쳐 사진과 같이 포스트 생성에 실패했다는 에러 메시지가 뜨게됩니다. 네트워크 탭에 보면, 포스트 부분은 잘 전달이 되는거같은데 이미지 생성에 관한 결과가 보이지 않는 것으로 보아 이미지 생성 관련 코드에서 문제가 생긴것같은데 무슨 문제일까요??..ㅠ 아래는 해당 코드들입니다. 이미지 생성 관련 코드를 가져왔는데 혹여나 다른 부분의 코드가 필요하면 추가 업로드 드리겠습니다. api/post.ts import type { PostEntity } from './../types'; import supabase from '@/lib/supabase'; export async function createPost(content: string) { const { data, error } = await supabase .from('post') .insert({ content }) .select() .single() if (error) throw error return data } export async function createPostWithImages({ content, images, userId }: { content: string images: File[] userId: string }) { // 1. 새로운 포스트 생성 (맨 위에서 생성한 포스트 비동기 함수 가져오기) const post = await createPost(content) if (images.length === 0) return post // 2. 이미지 업로드 try { const imageUrls = await Promise.all( images.map((image) => { const fileExtension = image.name.split(".").pop() || "webp" const fileName = `${Date.now()}-${crypto.randomUUID()}.${fileExtension}` const filePath = `${userId}/${post.id}/${fileName}` return uploadImage({ file: image, filePath }) }) ) // 3. 포스트 테이블 업데이트 const updatedPost = await updatePost({ id: post.id, image_urls: imageUrls }) return updatedPost } catch(error) { await deletePost(post.id) throw error } } export async function updatePost(post: Partial<PostEntity> & { id: number }) { const { data, error } = await supabase .from("post") .update(post) .eq("id", post.id) .select() .single() if (error) throw error return data } export async function deletePost(id: number) { const { data, error } = await supabase .from("post") .delete() .eq("id", id) .select() .single() if (error) throw error return data } hooks/mutations/post/use-create-post.ts import type { UseMutationCallback } from './../../../types'; import { createPost, createPostWithImages } from '@/api/post'; import { useMutation } from '@tanstack/react-query'; export function useCreatePost(callbacks?:UseMutationCallback) { return useMutation({ mutationFn: createPostWithImages, onSuccess: () => { if(callbacks?.onSuccess) callbacks.onSuccess() }, onError: (error) => { if (callbacks?.onError) callbacks.onError(error) } }) } components/modal/post-editor-modal.tsx import { Button } from '@/components/ui/button' import { Dialog, DialogContent, DialogTitle } from '@/components/ui/dialog' import { useCreatePost } from '@/hooks/mutations/post/use-create-post' import { usePostEditorModal } from '@/store/post-editor-modal' import { useSession } from '@/store/session' import { ImageIcon, XIcon } from 'lucide-react' import { useRef, useState, useEffect, ChangeEvent } from 'react' import { toast } from "sonner" import { Carousel, CarouselContent, CarouselItem } from '../ui/carousel' type Image = { file: File, previewUrl: string } export default function PostEditorModal() { const session = useSession() const { isOpen, close } = usePostEditorModal() const { mutate: createPost, isPending: isCreatePostPending } = useCreatePost({ onSuccess: () => { close() }, onError: (error) => { toast.error("포스트 생성에 실패했습니다", { position: "top-center" }) } }) const [content, setContent] = useState("") const [images, setImages] = useState<Image[]>([]) const textareaRef = useRef<HTMLTextAreaElement>(null) const fileInputRef = useRef<HTMLInputElement>(null) const handleCloseModal = () => { close() } const handleCreatePostClick = () => { if (content.trim() === "") return createPost({ content, images: images.map((image) => image.file), userId: session!.user.id }) } const handleSelectImages = (e:ChangeEvent<HTMLInputElement>) => { if (e.target.files) { const files = Array.from(e.target.files) files.forEach((file) => { setImages((prev) => [ ...prev, { file, previewUrl: URL.createObjectURL(file) }, ]) }) } e.target.value = "" } const handleDeleteImage = (image:Image) => { setImages((prevImages) => prevImages.filter((item) => item.previewUrl !== image.previewUrl)) } useEffect(() => { if (textareaRef.current) { textareaRef.current.style.height = "auto" textareaRef.current.style.height = textareaRef.current.scrollHeight + "px" } }, [content]) useEffect(() => { if (!isOpen) return textareaRef.current?.focus() setContent("") setImages([]) }, [isOpen]) return ( <Dialog open={isOpen} onOpenChange={handleCloseModal}> <DialogContent className="max-h-[90vh]"> <DialogTitle>포스트 작성</DialogTitle> <textarea disabled={isCreatePostPending} ref={textareaRef} value={content} onChange={(e) => setContent(e.target.value)} className="max-h-125 min-h-25 focus:outline-none" placeholder="무슨 일이 있었나요?" /> <input onChange={handleSelectImages} ref={fileInputRef} type="file" accept="image/*" multiple className="hidden" /> {images.length > 0 && <Carousel> <CarouselContent> {images.map((image) => <CarouselItem className="basis-2/5" key={image.previewUrl}> <div className="relative"> <img src={image.previewUrl} className="h-full w-full rounded-sm object-cover" /> <div onClick={() => handleDeleteImage(image)} className="absolute top-0 right-0 m-1 cursor-pointer rounded-full bg-black/30 p-1" > <XIcon className="h-4 w-4 text-white"/> </div> </div> </CarouselItem>)} </CarouselContent> </Carousel>} <Button onClick={() => { fileInputRef.current?.click() }} variant={"outline"} className="cursor=pointer" > <ImageIcon/> 이미지 추가</Button> <Button disabled={isCreatePostPending} onClick={handleCreatePostClick} className="cursor=pointer"> 저장 </Button> </DialogContent> </Dialog> ) }
react typescript react-query supabase zustand
rkdla666
2026-07-10T09:02:45.932Z
댓글 2
좋아요 0
조회수 58
해결됨
한 입 크기로 잘라먹는 React.js 실전 프로젝트 - SNS 편
강사님, 강의 너무 잘 듣고 있습니다. 그런데 강의자료가 Next.js 도 그렇고 깔끔하게 잘 만드시던데 무엇으로 어떻게 제작하시는지 간략히 설명 좀 해주시면 감사하겠습니다.
react typescript react-query supabase zustand
아리마
2026-06-25T06:06:02.916Z
댓글 2
좋아요 0
조회수 67
미해결
한 입 크기로 잘라먹는 React.js 실전 프로젝트 - SNS 편
안녕하세요! 비밀번호 재설정 이메일의 링크를 클릭한 후 비밀번호를 변경했는데, 같은 링크로 다시 접속해도 계속 비밀번호가 변경되는 것을 확인했습니다. 재설정 링크를 1회 사용 후 만료되게 하려면 어떻게 해야하나요?
react typescript react-query supabase zustand
쉬었음루피
2026-06-23T10:57:06.694Z
댓글 1
좋아요 0
조회수 65
미해결
타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게
강의를 막상 보면서 하는 건 쉬운데 미션에서 적용하는 것이 너무 어렵네요. 조금 빈 구멍이 생겨도 완강하는 것이 좋은 것인지, 구멍이 좀 생기지 않도록 끝까지 반복하면서 늦더라도 구멍이 생기지 않도록 하는 것이 좋은것인지 궁금합니다.
react react-router redux-toolkit zustand react.js
양승근
2026-06-21T14:23:55.732Z
댓글 2
좋아요 0
조회수 63
미해결
타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게
책에서는 styled-components를 더이상 추천하지 않는다고 하셨는데요. 강의에서는 비교적 비중을 높게 두시고 강의하시는 것 같은데요. 처음하는 입장에서 공부 방향을 어떻게 잡고 가야 할까요?
react react-router redux-toolkit zustand react.js
양승근
2026-06-21T14:20:01.813Z
댓글 2
좋아요 0
조회수 48
해결됨
한 입 크기로 잘라먹는 React.js 실전 프로젝트 - SNS 편
안녕하세요 정환님. 저는 정환님의 강의를 모두 구매해서 수강하고 있는 수강생입니다. 현재는 바이브 코딩 강의를 제외한 강의들을 모두 수강했고, 지금은 복습을 진행하고 있습니다. 복습과 함께 프론트엔드 신입 지원용 개인 프로젝트를 준비하고 있는데, 정환님께 배운 내용을 최대한 활용해 보고 싶어서 질문드립니다. 개인 프로젝트 기술 스택은 Next.js + TanStack Query + Supabase 기반으로 생각하고 있습니다. 1. 제가 이전에 영어학원에서 근무한 경험이 있어서, 그 경험을 바탕으로 영어와 관련된 서비스를 만들어보려고 합니다. 예를 들어 영어 원서 학습 서비스나 영어 단어장 서비스 등을 생각하고 있는데, 이런 주제가 프론트엔드 신입 포트폴리오용 개인 프로젝트로 적절할지 궁금합니다. 2. 혹시 프론트엔드 신입 포트폴리오용으로 추천해 주실 만한 프로젝트 주제가 있을까요? 3. 현재 React, TypeScript, Next.js, TanStack Query를 학습하고 복습 중입니다. 신입 프론트엔드 개발자로 취업하기 위해 어느 정도 수준까지 준비하는 것이 좋을지, 그리고 추가로 공부하면 좋을 부분이 있다면 조언 부탁드립니다. 4. 정환님의 바이브 코딩 강의를 수강한 이후에는 AI를 활용한 프로젝트도 하나 진행해 보고 싶습니다. 프론트엔드 신입 포트폴리오 관점에서 추천해 주실 만한 AI 프로젝트 주제가 있을까요? 5.포트폴리오를 준비하는 입장에서 아래 항목들의 우선순위를 어떻게 가져가는 것이 좋을지도 궁금합니다. 현재 준비 기간이 넉넉하지 않아 세 가지를 모두 진행하지 못할 수도 있다는 생각이 들어서, 어떤 순서로 준비하는 것이 가장 효과적일지 조언 부탁드립니다. 1) 개인 프로젝트 2) AI 프로젝트 3) 팀 프로젝트 질문이 많았는데 시간 내어 읽어주셔서 감사합니다. 정환님 강의를 통해 정말 많은 도움을 받고 있습니다. 항상 좋은 강의 만들어주셔서 감사드립니다.
react typescript react-query supabase zustand
imhj11777
2026-06-17T07:49:56.048Z
댓글 1
좋아요 2
조회수 77
미해결
타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게
안녕하세요 위 제목 같이 import {} 중괄호 차이점 1: import useCounter from "../context/counter/useCounter"; 2: import {useCounter} from "../context/counter/useCounter"; 중괄호 할때와 안할때의 차이점을 알고 싶습니다. 문의 답변 부탁드립니다.
react react-router redux-toolkit zustand react.js
bluescreen
2026-05-27T13:38:43.518Z
댓글 2
좋아요 0
조회수 58
미해결
타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게
후 connect 를 시도하면 아래와 같이 권한 문제로 접속이 안되고 있습니다. (source tree는 관리자 권한으로 실행 되고 있습니다.) 강사님~ 무엇이 문제인지요?
react react-router redux-toolkit zustand react.js
bluescreen
2026-05-26T01:22:46.383Z
댓글 2
좋아요 0
조회수 73
미해결
타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게
제공되는 react_ code.zip 중에 .. D:\su\code\SECTION11\11-02 D:\su\code\SECTION11\11-03 안에 소스가 없네요. 당연히 제가 작성하면 되겠지만... 참조하는 차원에서.. ㅡㅡ;; 소스를 얻을 수 있을까요? 다른 폴더안에는 소스가 제공되고 있는데 말이줘 ..
react react-router redux-toolkit zustand react.js
bluescreen
2026-05-25T02:59:52.264Z
댓글 2
좋아요 0
조회수 71
미해결
타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게
구입을 했는데 ... 아래 비활성화 된 강의 리스트는 뭔가요? 뒤 강의를 보고 싶거든요
react react-router redux-toolkit zustand react.js
bluescreen
2026-05-21T08:46:33.359Z
댓글 2
좋아요 0
조회수 61
해결됨
React 마스터 클래스: Part 3 - 실무 핵심 라이브러리 정복 (TypeScript, Zustand, React Hook Form, TanStack Query)
강의 잘 듣고있습니다. 한 가지 궁금한 점이 있어 질문드립니다. "App.tsx를 Provider로 감싸는 순간 그 아래 모든 컴포넌트가 서버 컴포넌트로서의 최적화 기회를 잃는다"는 부분이 잘 이해되지 않습니다. 제가 알기로는 Provider를 children prop으로 받는 composition pattern으로 작성하면, Provider 자체는 Client Component여도 그 안에 들어가는 children은 Server Component로 유지될 수 있는 것으로 알고 있습니다. Next.js App Router의 RootLayout 에서 <Providers>{children}</Providers> 형태로 쓰는 패턴이 그 예시라고 알고 있고요. 이 경우에도 RSC 최적화 기회를 잃는다고 보시는 건지, 아니면 제가 놓치고 있는 다른 맥락이 있는지 궁금합니다.
javascript react typescript frontend zustand
Eden
2026-05-21T05:59:18.300Z
댓글 3
좋아요 0
조회수 114
미해결
타입스크립트로 배우는 리액트(React.js) : 기초부터 최신 기술까지 완벽하게
안녕하세요. 설명하시는 개념들이 매우 어렵게 느껴집니다. 굉장히 기본 개념을 설명하고 계신 것 같은데요. 강의를 어떤 자세로 수강해야 할까요? 부분 부분 계속 끊어져 있으니 이해가 안 됩니다. 책을 구매해서 보면 도움이 될까요?
react react-router redux-toolkit zustand react.js
2026-05-20T12:57:28.860Z
댓글 2
좋아요 0
조회수 66