묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결React 기반 Gatsby로 기술 블로그 개발하기 v2
렌더링 문제
pages/index.tsx 파일이 먼저 렌더링이 되어야되는데pages/{contentfulPost.slug}.tsx 파일 이 먼저 렌더링 되는 현상이 생겼는데 이거는 무슨경우인가요 ? 갑자기 이렇게 되었습니다. 캐시 제거랑 재부팅까지했지만 해결을 못하고있습니다..
-
해결됨Supabase, Next 풀 스택 시작하기 (feat. 슈파베이스 OAuth, nextjs 14)
타입에러에 관해 질문있습니다
아래와 같은 타입에러가 발생했습니다.데이터베이스와 todoDto모두 설정 및 정상적으로 가져온거 같은데요마우스를 올려보고 에러내용도 확인해보면 타입은 다 같게 설정되어있는거 같습니다.타입자체를 비교해서 대입 하려해도 에러가나오네요..플러그인을 통해서 시각화해서 좀 더 자세하게 머가 문제인지 비교해봐도 타입이 같습니다..혹시 뭐가 문제인지 알 수 있을까요?...
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
강사님 REST API와 GraphQL에 관하여 질문이 있습니다.
graphql의 장점이 딱 원하는 데이터만 가져온다는 것은 이해가 되는데, REST API도 딱 원하는 DB 컬럼만 요청해서 가져오거나 할 수도 있지 않나요? 이게 어떠한 차이가 있나 궁금합니다. ㅎㅎ
-
해결됨기초부터 배우는 Next YTMusic 클론 코딩 (with next.js 14, UI 마스터)
11.5 Channel 노래,앨범 section 강의중
안녕하세요 선생님 ㅎchannel쪽 진행하고 있었는데 앨범 밑에 PlayListCarousel이 크기가 이상하게 나오네여 ㅠㅠ 코드를 다똑같이 써도 안되서 질문드립니다! channel/[id]/page.tsximport HeaderBgChanger from "@/components/HeaderBgChanger"; import PagePadding from "@/components/PagePadding"; import PlayListCarousel from "@/components/PlayListCarousel"; import SongCardRowExpand from "@/components/SongCardRowExpand"; import DarkButton from "@/components/elements/DarkButton"; import WhiteButton from "@/components/elements/WhiteButton"; import { getChannelById } from "@/lib/dummyData"; import { getRandomElementFromArray } from "@/lib/utils"; import { permanentRedirect } from "next/navigation"; import React from "react"; import { FiMusic, FiShuffle } from "react-icons/fi"; interface ChannelPageProps { params: { id: string; }; } const page = async (props: ChannelPageProps) => { const channel = await getChannelById(Number(props.params.id)); if (!channel) permanentRedirect("/"); const imageSrc = getRandomElementFromArray(channel.songList)?.imageSrc; return ( <PagePadding> <HeaderBgChanger imageSrc={imageSrc} /> <div className="mt-[150px]"></div> <section> <div className=" text-[28px] font-bold">{channel.name}</div> <article className="mt-4 lg:hidden"> <div> <DarkButton className={"w-[230px] flex justify-center"} label={"구독중 99만"} /> </div> <div className="flex flex-row gap-4 mt-4"> <WhiteButton label={"셔플"} icon={<FiShuffle size={16}></FiShuffle>} /> <WhiteButton label={"뮤직 스테이션"} icon={<FiMusic size={16} />} /> </div> </article> <div className="hidden lg:flex flex-row items-center gap-4 text-[14px] mt-4"> <WhiteButton label={"셔플"} icon={<FiShuffle size={16}></FiShuffle>} /> <WhiteButton label={"뮤직 스테이션"} icon={<FiMusic size={16} />} /> <DarkButton className={"w-[230px] flex justify-center"} label={"구독중 99만"} /> </div> </section> <section className="mt-[80px]"> <div className=" text-[28px] font-bold">노래</div> <div className="mt-[20px]"> <ul className="flex flex-col gap-2"> {channel.songList.map((song, key) => { return <SongCardRowExpand song={song} key={key} />; })} </ul> </div> </section> <section className="mt-[80px]"> <div className=" text-[28px] font-bold">앨범</div> <PlayListCarousel playlistArray={channel.playlistArray} /> </section> <section className="mt-[80px]"></section> </PagePadding> ); }; export default page;PlayListCarousel.tsximport { Playlist } from "@/types"; import React from "react"; import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, } from "@/components/ui/carousel"; import PlayListCard from "./PlayListCard"; interface PlayListCarouselProps { title?: string; subTitle?: string; Thumbnail?: React.ReactNode; playlistArray?: Playlist[]; } const PlayListCarousel: React.FC<PlayListCarouselProps> = ({ title, subTitle, Thumbnail, playlistArray, }) => { return ( <div className="w-full"> <Carousel> <div className="flex flex-row justify-between items-end my-2"> <article className="flex flex-row gap-3"> {Thumbnail} <div className="flex flex-col justify-center"> <div> {subTitle && ( <div className=" text-neutral-500">{subTitle}</div> )} </div> <div className="text-[34px] font-bold leading-[34px] "> {title} </div> </div> </article> <div className="relative left-[-45px]"> <div className="absolute bottom-[20px]"> <CarouselPrevious className="right-2" /> <CarouselNext className=" left-2" /> </div> </div> </div> <CarouselContent className="mt-4"> {playlistArray?.map((playlist, index) => { return ( <CarouselItem key={index} className="basis-1/2 md:basis-1/3 lg:basis-1/4 xl:basis-1/5" > <PlayListCard playlist={playlist} /> </CarouselItem> ); })} </CarouselContent> </Carousel> </div> ); }; export default PlayListCarousel;
-
해결됨[React / VanillaJS] UI 요소 직접 만들기 Part 2
createPortal 활용해서 modal 만들 때 활용한 MutationObserver 코드 관련 질문
import { useEffect, useRef } from "react" const mutationObserverOption: MutationObserverInit = { childList: true, subtree: true } const ModalRoot = () => { const ref = useRef<HTMLDivElement>(null); useEffect(() => { let observer: MutationObserver if (ref.current) { observer = new MutationObserver(() => { const size = ref.current?.childNodes.length || 0 document.body.classList.toggle('no-scroll', size > 0) }) observer.observe(ref.current, mutationObserverOption) } return () => { observer.disconnect() } }, []) return (<div id="modalRoot" ref={ref}/>) } export default ModalRoot; 수업시간에 구현 되었던 코드가 어떤 순서로 동작하는지 콘솔로 확인해봤습니다. 제가 확인해 봤을 땐 처음 페이지가 렌더링 될 때 1. ModalRoot 컴포넌트가 실행 2. modalRoot div가 생성 3. useEffect가 실행4. useEffect의 Clean Up 작동까지는 예상대로 진행되었습니다. 하지만 이후에 이해가 안되는 부분이 있습니다.질문 1) 이후 useEffect가 다시 실행되는데, 의존성도 없는데 어떻게 다시 실행되는지 궁금합니다.질문 2) 영상에서 모달 버튼을 누르면 useEffect의 조건문에서 size를 콘솔로 확인하셨는데, ModalRoot 컴포넌트가 재실행되지 않고 어떻게 size를 확인할 수 있는지 궁금합니다.
-
해결됨React 기반 Gatsby로 기술 블로그 개발하기 v2
깃 액션 활용
name: Deploy Blog on: push: branches: develop jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 # 원하는 Github Secrets을 불러와 env 파일을 생성해줍니다. - name: Generate env file run: | echo "CONTENTFUL_ACCESS_TOKEN=$CONTENTFUL_ACCESS_TOKEN" >> .env echo "CONTENTFUL_SPACE_ID=$CONTENTFUL_SPACE_ID" >> .env env: CONTENTFUL_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_ACCESS_TOKEN }} CONTENTFUL_SPACE_ID: ${{ secrets.CONTENTFUL_SPACE_ID }} - name: Deploy gatsby uses: enriikke/gatsby-gh-pages-action@v2 with: access-token: ${{ secrets.DEPLOYMENT_ACCESS_TOKEN }} deploy-branch: main gatsby-args: --verbosedevelop 브런치에서 위 코드를 작성하고 git push origin develop 을했는데 액션에 동작을 안합니다.https://github.com/Choi-jeonghoon/Jeong-hoon.github.io/actions/new
-
해결됨React 기반 Gatsby로 기술 블로그 개발하기 v2
code 강조가 안됨니다..
코드블럭 테스트language::typescriptexport const { auth, signIn, signOut, handlers } = NextAuth({등등을 존재하는데 아래와같이 코드는 작성했는데 코드 강조가 안되고있습니다. 뭐가문제일까요? import React from 'react' import { ContentfulRichTextGatsbyReference, renderRichText, } from 'gatsby-source-contentful/rich-text' import { getImage } from 'gatsby-plugin-image' import { NodeRenderer, Options } from '@contentful/rich-text-react-renderer' import { BLOCKS, INLINES, MARKS } from '@contentful/rich-text-types' import { Blockquote, Heading, Image, HorizontalRule, OrderedList, UnorderedList, Link, Code, } from './node' export const HEADERS = [ BLOCKS.HEADING_1, BLOCKS.HEADING_2, BLOCKS.HEADING_3, ] as const const CODE_METADATA_REGEX = /^language::(\w+)/ const options: Options = { renderMark: { [MARKS.CODE]: text => { const isBlock = !!text && CODE_METADATA_REGEX.test(text.toString()) if (!isBlock) return <Code>{text}</Code> else return ( <Code isBlock className={`language-${ CODE_METADATA_REGEX.exec(text.toString())?.[1] }`} > {text.toString().replace(CODE_METADATA_REGEX, '').trimStart()} </Code> ) }, }, renderNode: { ...HEADERS.reduce<{ [block: string]: NodeRenderer }>((nodes, header) => { nodes[header] = (node, children) => ( <Heading type={header}>{children}</Heading> ) return nodes }, {}), [BLOCKS.OL_LIST]: (_node, children) => ( <OrderedList>{children}</OrderedList> ), [BLOCKS.UL_LIST]: (_node, children) => ( <UnorderedList>{children}</UnorderedList> ), [BLOCKS.HR]: () => <HorizontalRule />, [BLOCKS.QUOTE]: (_node, children) => <Blockquote>{children}</Blockquote>, [BLOCKS.EMBEDDED_ASSET]: node => { const { gatsbyImageData, description } = node.data.target const image = getImage(gatsbyImageData) if (image) return <Image image={image} alt={description} /> }, [INLINES.HYPERLINK]: (node, children) => ( <Link href={node.data.uri as string} target="_blank" rel="noopener noreferrer" > {children} </Link> ), }, } export default function useRenderRichText({ raw, references, }: Queries.ContentfulPostContent) { if (!raw) return null return renderRichText( { raw, references: references as unknown as ContentfulRichTextGatsbyReference[], }, options, ) }import React from 'react' import { GatsbyBrowser } from 'gatsby' import Layout from './src/components/common/Layout' import 'prismjs/themes/prism-tomorrow.min.css' export const wrapPageElement: GatsbyBrowser['wrapPageElement'] = ({ element, props, }) => { return <Layout {...props}>{element}</Layout> } import React from 'react' import { GatsbyBrowser } from 'gatsby' import Layout from './src/components/common/Layout' import 'prismjs/themes/prism-tomorrow.min.css' export const wrapPageElement: GatsbyBrowser['wrapPageElement'] = ({ element, props, }) => { return <Layout {...props}>{element}</Layout> }import React, { useEffect } from 'react' import styled from 'styled-components' import { TPostBodyProps } from '../../types/PostBody' import Prism from 'prismjs' import 'prismjs/components/prism-typescript' import useRenderRichText from '../../hooks/useRenderRichText' const Wrapper = styled.div` position: relative; display: grid; grid-template-columns: 1fr 220px; grid-gap: 30px; justify-content: space-between; align-items: flex-start; padding-top: 100px; ` const Content = styled.div` overflow: auto; display: flex; flex-direction: column; gap: 100px; font-size: 16px; line-height: 2; word-break: break-word; ` export default function PostBody({ content }: TPostBodyProps) { const richText = useRenderRichText(content) useEffect(() => { Prism.highlightAll() }, []) return ( <Wrapper> <Content> <div id="content">{richText}</div> {/* 댓글 컴포넌트가 들어갈 자리 */} </Content> {/* 플로팅 목차 컴포넌트가 들어갈 자리 */} </Wrapper> ) }
-
미해결[리액트 1부] 만들고 비교하며 학습하는 리액트 (React)
localhost:8080 접속 불가
안녕하세요 선생님리액트 프로젝트를 본격적으로 하기 위해 npm i -> npm start로 localhost:8080에 접속해야 하는데 자꾸 오류가 나오네요 제가 군대에서 수업 듣고 있어서 vscode는 설치를 못하고 대안으로 무료클라우딩 사이트 replit을 이용중입니다. 폴더구조 정확히 맞게 했고 100%그대로 따라 옮겼는데 왜 이런 오류가 나오는지 모르겠습니다.어떻게 해결해야 될까요? 공부해야 하는데 여기에 막혀서 하루종일 시간 썼네요 ㅠ 답변주시면 감사하겠습니다!!
-
미해결[리액트 1부] 만들고 비교하며 학습하는 리액트 (React)
최근검색어 3 풀이에서
안녕하세요 선생님 수업 잘듣고 있습니다.다소 수준이 높은 수업이라 조금 헤매고 있지만요..최근 검색어 3에서 2분 41초 경에store js에서 15번째 줄 search(keyword) { this.addHistory(keyword); return this.storage.productData.filter((product) => product.name.includes(keyword) ); }이 부분이 있는데요. 이 부분때문에 store의 search가 addHistory를 호출하고 상태변화가 이루어질 수 있는데 (addhistory 내용만 수정하면 main.js의 코드를 수정안해도 목표로 하는 최근 검색어에 목록 추가를 할 수 있어서요)굳이 4분 1초 경에 main.js의 search에서 setstate를 건드리시는 이유가 무엇인가요?이미 상태변화가 store.js에서 작성한 코드 때문에 이루어지고 있기때문에 다소 역할이 중복된 코드가 아닌가해서요답변주시면 감사하겠습니다
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
Next 14 사용해도 될까요?
궁금합미다
-
해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
value 오류 문의
🚨 아래의 가이드라인을 꼭 읽고 질문을 올려주시기 바랍니다 🚨질문 하시기 전에 꼭 확인해주세요- 질문 전 구글에 먼저 검색해보세요 (답변을 기다리는 시간을 아낄 수 있습니다)- 코드에 오타가 없는지 면밀히 체크해보세요 (Date와 Data를 많이 헷갈리십니다)- 이전에 올린 질문에 달린 답변들에 꼭 반응해주세요 (질문에 대한 답변만 받으시고 쌩 가시면 속상해요 😢)질문 하실때 꼭 확인하세요- 제목만 보고도 무슨 문제가 있는지 대충 알 수 있도록 자세한 제목을 정해주세요 (단순 단어 X)- 질문의 배경정보를 제공해주세요 (이 문제가 언제 어떻게 발생했고 어디까지 시도해보셨는지)- 문제를 재현하도록 코드샌드박스나 깃허브 링크로 전달해주세요 (프로젝트 코드에서 문제가 발생할 경우)- 답변이 달렸다면 꼭 확인하고 반응을 남겨주세요- 강의의 몇 분 몇 초 관련 질문인지 알려주세요!- 서로 예의를 지키며 존중하는 문화를 만들어가요. - 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.아래 오류가 자꾸 뜨는데 이유를 모르겠습니다...input 태그에 텍스트도 써지지 않습니다.onchange2 도 이어서 작성하면 오류가 발생하여 지워버렸습니다ㅠㅠWarning: You provided a value prop to a form field without an onChange handler. This will render a read-only field. If the field should be mutable use defaultValue. Otherwise, set either onChange or readOnly.
-
해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
감정일기장 응용공부
마지막 주차에서 감정일기장을 주차별로 된 것으로 만들어보라고 하셔서 만들기를 시도했습니다.그러나 도저히 어떻게 해야할지 막막해서 감정일기장 코드들을 챗지피티에 복붙하고 주차별로 만들어달라고 했고 완성했습니다(챗지피티가 알려준 코드들은 모두 이해됩니다)이렇게 학습하는 것이 과연적절할까요?? 또한 감정일기장을 주차별로 만드는것외에 감정일기장을 어떤식으로 변형하면 좋을지 궁금합니다!!
-
해결됨[React / VanillaJS] UI 요소 직접 만들기 Part 2
강의자료 (보일러플레이트) 다운로드 관련 질문
강의 커리큘럼을 보면 "강의자료 (완성본)"과 "강의자료 (보일러플레이트)" 다운로드를 구분해 두셨는데, 다운로드는 "강의자료 (완성본)"만 만 받게 되어 있는거 같습니다.혹시 보일러플레이트 강의자료는 아직 준비가 되지 않은것일까요?완성본 README.md에 있는 `git clone https://github.com/fe-ui-study/ui-study.git`도 Repository를 찾지 못하고 있습니다.
-
해결됨코드로 배우는 React with 스프링부트 API서버
router 이동 질문 드립니다.
안녕하세요. 열심히 강의 듣고 있습니다. ... react에서 router 이동에 궁금한거 잇어서 질문 드려요1root 의 라우터에는 TodoIndex와 ProductsIndex 2개의 페이지가 있습니다. ............ 생략 ..............{ path: "todo", element: ...<TodoIndex/>..., children: todoRouter() }, { path: "products", element: ... <ProductsIndex/>..., children: productsRouter() }2.TodoIndex의 child은 todoRoter이고 add의 TodoAdd와 mdify의 TodoModify가 있습니다. { path: "add", element: ...<TodoAdd/>... }, { path: "modify/:tno", element: ...<TodoModify/>... }ProductsIndex의 child은 productsRouter이고 add의 ProductList와 mdify의 ProductModify가 있습니다. 현재 ../products/add 에 있다고 했을때 add 페이지에 있는 버튼을 누르면 ../todo/add 로 점프해서 이동하려면 어떻게 navigate 해야되나요? todo/add에서 todo/modify 이런식의 같은 폴더 레벨이면 쉽게 이동되던데 ...
-
미해결코드로 배우는 React with 스프링부트 API서버
Product 컨트롤러 api 결과값 리턴 질문
상품 등록이나 수정을 하고나서return Map.of("result", "Success")이렇게 리턴해주셨는데실무에서 이런 방식을 많이 사용하나요 아니면 교육목적이기 때문에 조금 러프하게 하신건가요??이번 강의를 보고 실무와 가깝게 프로젝트를 진행하고 싶은데 이렇게 Map에 간단하게 리턴할지 아니면 api마다 매번ResponseEntity에 Http Status Code 담아 리턴해야 할지 기준을 모르겠습니다.제 목적에 맞게 하려면 어떤 방식으로 api 결과를 리턴해줘야 할까요??
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
Like 검색으로 구현하려면 어떻게 하면 될까요?
강의대로 구현하니 제목과 설명의 full text를 입력했을 때만 검색이 되는데요Like 검색으로 구현하려면 어떻게 하면 될까요?
-
미해결React Router 완전 정복
코드 제공 되나요?
코드 제공 됩니까?
-
해결됨처음 만난 리액트(React)
createRoot도 잘 했는데 에러가 나네요
createRoot도 잘 되어있고 하는데도 이 에러가 뜹니다..import Clock from "./chapter_04/Clock"; const root = ReactDOM.createRoot(document.getElementById("root")); setInterval(() => { root.render( <React.StrictMode> <Clock /> </React.StrictMode> ); }, 1000); reportWebVitals();ERRORreact_dom_client__WEBPACK_IMPORTED_MODULE_1__.render is not a function TypeError: react_dom_client__WEBPACK_IMPORTED_MODULE_1__.render is not a function at http://localhost:3000/static/js/bundle.js:114:49
-
해결됨Supabase, Next 풀 스택 시작하기 (feat. 슈파베이스 OAuth, nextjs 14)
9.1 강의에서 생긴 servercomponent 변수
9.1장에서 user.action.ts의 getUser 함수에 serverComponent라는 속성이 갑자기 생겨났는데 이거에 대한 설명이 필요한 것 같습니다.
-
해결됨만들면서 배우는 리액트 : 기초
메인글자수정...
MainCard에 처음 나오는 이미지에 써지는 글자의 스타일은 어디서 수정을 해줘야 하는걸까요?찾아서 나름 해봤는데 전혀 변경이 안되어서요input에 넣은 글자가 이미지 위에 나올때 ...그 글자의 크기,색상,폰트 등의스타일은 어디서 바꾸어야 하는지...