묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨Next + React Query로 SNS 서비스 만들기
현업에서 사용하는 마이그레이션 방식 문의
안녕하세요 제로초님, 강의 완강했습니다.덕분에 많은 지식 얻었었습니다. 감사합니다.이제 여기서 배운 내용을 바탕으로 제 리액트 프로젝트 하나를 next로 마이그레이션 해보려고 합니다.마이그레이션이 처음이라 막상하려고하니, 폴더 구조가 완전히 바뀌고, 거의 모든게 달라지기 때문에 어떻게 마이그레이션을 시작해 나갈지 의문이 듭니다. 구글링에서도 뚜렷하게 방법을 설명해주는 글이 보이지 않아 문의 드립니다.질문1. 기존 프로젝트는 git-flow 전략을 통해 v1.0.0까지 배포를 마친상태입니다. 마이그레이션을 해서 v2.0.0로 배포를 하면 좋을 것 같은데, 기존 develop 브랜치에서 feature/next-migration 브랜치를 따서 작업하는게 좋을까요?질문2. next를 설치하는 순간 많은 설정이 달라져서, 기존 코드 파일들을 그대로 두면 npm start시 에러가 날 것 같습니다. 현업에서는 기존 파일을 다 삭제하고 next의 디렉토리 구성을 만들어 놓은 다음에 다른 브랜치에서 코드를 복사해와서 재작성을 하나요? 아니면 다른 좋은 방법이 있나요?
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)
서버 실행 시 에러 관련하여 답변받고 1차 조치했는데 여전하여서 질문 남깁니다
data-source hostname db로 변경하라는 말씀 듣고 변경해보았는데 여전히 해결이 안되어서 질문 남깁니다
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 레딧 사이트 만들기(NextJS)(Pages Router)
엔티티 모두 작성 후 서버 실행 시 에러가 발생합니다
서버 실행 시 해당 에러가 발생해서 질문 남깁니다문제 파악에 도움될까해서 data-source.ts, server.ts 파일도 첨부합니다
-
해결됨코드로 배우는 React 19 with 스프링부트 API서버
강의 영상에 혹시 빠진게 있나요??
조금 전 있던 질문글 이랑 동일한 에러가 발생해서 코드 확인했더니 TodoController 클래스에서 put, delete를 구현하지 않았더라구요. 제가 뭔가 빼먹었나보다 하고 소스코드 찾아보니까 소스코드에는 있길래 소스코드 참고해서 해결했거든요. 그런데 그 다음에도 RootConfig 클래스를 만드는거나, CustomServletConfig 클래스에 addCorsMappings 메서드를 추가하는 과정을 소스코드 보면서 해결했었는데, 혹시 강의 영상에는 소스코드에 있는 내용 전부가 작성되는 과정이 나오는건 아닌걸까요? 제가 영상보다 코드치다 하면서 실수로 넘어간 부분이 있을수도 있는데, 강의 영상에는 빠져있고, 소스코드는 올라와 있는 부분들이 있는것 같아서요. 한번 확인 부탁드려도 될까요..? 제 착오였다면 죄송합니다 ㅠㅠ
-
미해결Next + React Query로 SNS 서비스 만들기
next aws s3 가능 여부 문의
혹시 aws s3로는 배포가 불가능 할까요??
-
미해결Next + React Query로 SNS 서비스 만들기
/login 라우팅시 발생하는 컴포넌트 업데이트 오류
Warning: Cannot update a component (`Router`) while rendering a different component (`RedirectLoginPage`). To locate the bad setState() call inside `RedirectLoginPage`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render at RedirectLoginPage (webpack-internal:///(app-pages-browser)/./src/app/(beforeLogin)/login/page.tsx:15:78) at StaticGenerationSearchParamsBailoutProvider (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/static-generation-searchparams-bailout-provider.js:15:11) at InnerLayoutRouter (webpack-internal:///(app-pages-browser)/./node_modules/next/dist/client/components/layout-router.js:240:11)로그인 버튼 클릭시 '/login' 이동하면 이런 Warning 이 발생하는데 빌드시에도 Error occurred prerendering page "/login". Read more: https://nextjs.org/docs/messages/prerender-error ReferenceError: location is not defined위 같은 에러가 발생합니다. location을 사용하는 부분도 없고, useRouter도 'next/navigation' 에 있는 것을 사용중입니다. 해결법으로는 useEffect로 감싸주는 법이 있어 useEffect((router.replace(path)) => []) 이런방식으로 해봤는데 오류는 해결되네요.하지만 오류 내용대로 해석해보면 렌더링 도중 set을 통한 상태변화를 하지 않는데 오류가 나는 이유는 뭔가요? return 으로 Main 컴포넌트를 그려주어야하는데 replace시 LoginModal의 컴포넌트를 그려주어야해서 렌더링해야할 컴포넌트가 겹쳐서 발생하는 문제인가요?
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
Cannot read properties of null (reading 'useRef') 오류 질문
강의에서 진행 된 요소 추가 전까진 정상 작동 되는 것 확인 했습니다. Menu 추가 후 아래와 같은 오류가 출력 됩니다. Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:1. You might have mismatching versions of React and the renderer (such as React DOM)2. You might be breaking the Rules of Hooks3. You might have more than one copy of React in the same appSee https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem. TypeError: Cannot read properties of null (reading 'useRef') at useRef (C:\Users\sion\node_modules\react\cjs\react.development.js:1630:21) at Object.render (C:\Users\sion\node_modules\antd\lib\menu\index.js:19:37) at ReactDOMServerRenderer.render (C:\Users\sion\Documents\prepare\front\node_modules\react-dom\cjs\react-dom-server.node.development.js:3535:44) at ReactDOMServerRenderer.read (C:\Users\sion\Documents\prepare\front\node_modules\react-dom\cjs\react-dom-server.node.development.js:3373:29) at renderToString (C:\Users\sion\Documents\prepare\front\node_modules\react-dom\cjs\react-dom-server.node.development.js:3988:27) at Object.renderPage (C:\Users\sion\Documents\prepare\front\node_modules\next\dist\next-server\server\render.js:50:851) at Document.getInitialProps (C:\Users\sion\Documents\prepare\front\.next\server\pages\_document.js:264:19) at loadGetInitialProps (C:\Users\sion\Documents\prepare\front\node_modules\next\dist\next-server\lib\utils.js:5:101) at renderToHTML (C:\Users\sion\Documents\prepare\front\node_modules\next\dist\next-server\server\render.js:50:1142) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) 터미널에 찍힌 로그입니다.react/react dom 버전은 동일함을 확인했고 16.14.0 버전 사용 중입니다. 구글링 중 react hook form을 인스톨 하라는 검색 결과가 있어 해당 패키지 설치 했습니다. 버전은 7.49.2 사용 중 입니다. 로컬에서 실행 된 화면입니다.
-
미해결
react 모바일 삼성인터넷으로 사이트 접속시 크롬 연결 팝업
안녕하세요react로 웹 페이지를 만들었는데만든 사이트를 모바일로 삼성인터넷 앱을 통해 접속하니깐 크롬 연결 팝업이 자동으로 계속 나오게 되더라구요혹시 코드상으로 크롬 연결 팝업이 뜨는걸 막을수있는 방법이 있을까요 ?
-
미해결Next + React Query로 SNS 서비스 만들기
섹션3 마지막 강의. suspense 관련 간단 질문입니다.
안녕하세요 강의 잘 듣고있습니다 제로초님! 질문 한 가지 있습니다!섹션3 마지막 강의 suspense 관련 간단 질문입니다.검색 엔진이 로딩화면을 긁어가서 SEO가 안 좋아지는 것을 막기위해서 preFetchInfiniteQuery를 통해 SSR를 구현해야한다고 하셨는데, 마지막에 알려주신 post 목록에 suspense로 따로 로딩을 구현한 부분은 검색 엔진에 감지 되나요? 만약에 감지가 되지 않는다면 가장 중요한 게시물의 내용이 안보이게되는 셈이 될텐데 괜찮나요?
-
해결됨손에 익는 Next.js - 공식 문서 훑어보기
비동기 호출, fetch, 라우트 핸들러 관련 질문입니다.
안녕하세요! revalidateTag 함수 관련 코드를 보다가 궁금한 점이 생겨서 질문 드립니다!우선 fetch를 통해 데이터를 받아오는 비동기 호출은 서버 컴포넌트에서만 호출할 수 있다고 해서 날씨API나 시간API를 서버 컴포넌트에서 fetch를 이용해 받아오는 것 까지는 이해가 갔습니다.그런데 아래와 같이 캐시를 비우는 버튼을 만들 때는 클라이언트 컴포넌트에서 fetch가 사용되었습니다. 'use client' type Props = { tag : string } export default function RevalidateButton({tag} : Props) { const handleClick = async () => { const res = await fetch(`/api/revalidate?tag=${tag}`, { method : 'POST' }) console.log(res) } return <button onClick={handleClick}>캐시 비우기</button> }일단 이벤트 핸들러는 클라이언트 컴포넌트에서 사용 해야 되서 'use client'를 작성하는 것도 이해가 갔습니다. 그리고 revalidateTag 함수는 서버 컴포넌트에서 호출되야 하니깐 'api요청을 보내야 되서 fetch를 사용해야 한다' 라고 이해를 했는데요.. 그럼 혼란 스러운게..'fetch비동기 호출은 서버 컴포넌트에서 하라고 되어 있는데 revalidateTag같이 서버 컴포넌트에서 동작하는 함수를 호출하기 위해서는 어쩔 수 없이 fetch를 클라이언트 컴포넌트에서 사용해야한다' 라고 이해 하는게 맞을까요??그리고 위의 코드에서 method : 'POST' 라고 세팅하여 주셨는데 보내는 방식은 POST로 정해져 있는 것인지, 다른 메서드 (get, update, delete)로 사용하면 안되는 것인지 궁금합니다!아래는 핸드북(3. Next.js 손에 익히기 / 7.날씨데이터 조회하기 / 데이터 재검증하기 )에 설명해주신 내용인데요! revalidateTag는 서버 사이드에서 호출 가능합니다. 하지만 캐시를 풀어달라는 요청은 클라이언트(브라우저)에서 만들어집니다. 때문에 API 형태로 revalidateTag를 호출할 수 있도록 만들어야 합니다. Next.js에서의 API는 라우트 핸들러를 통해 만들 수 있습니다."캐시를 풀어달라는 요청은 클라이언트(브라우저)에서 만들어집니다." 라는 말이 RevalidateButton 버튼을 클릭했을 때 handleClick 함수가 호출되는 때를 말씀하신 것인지 궁금합니다. 아래는 revalidateTag가 호출되는 서버 컴포넌트 코드입니다. import { revalidateTag } from "next/cache"; import { NextRequest, NextResponse } from "next/server"; export async function POST(req:NextRequest) { const tag = req.nextUrl.searchParams.get('tag'); if(!tag) throw new Error('태그는 필수!!') revalidateTag(tag) return NextResponse.json({message : '재검증에 성공했습니다', tag}) }revalidateTag 함수는 호출시 에러가 발생하는 경우는 없는건가요?? 제 생각에는 revalidateTag도 제대로 작동을 안할 수도 있으니깐 try catch 문으로 감싸서 호출하는게 맞지 않을까? 생각이 들었는데 그렇게 안해도 되는 것인지 궁금합니다!
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
createUploadLink사용 할 때 오류가 발생합니다.
import에 문제가 발생했다고 하는 것 같은데 아무리 찾아봐도 해결이 안됩니다.ㅠ 어찌해야할까요
-
해결됨따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
강의 업데이트 질문드립니다
안녕하세요.채팅앱은 구름에듀에서 수강중입니다.구름에듀에도 강의 업데이트 가능하시면 부탁드립니다.좋은 강의 항상 감사합니다.
-
해결됨Next + React Query로 SNS 서비스 만들기
x.com에 모달창에 url을 적용시킨 이유가 있을까요?
x.com 을 보면 로그인도 그렇고 게시글 올릴때도 그렇고 모달창이 뜰때마다 그냥 화면에 띄우는 방식이 아니라 저렇게 모달창을 띄울수 있는 url 따로 만든 이유가 뭘까요? 관리가 더 편해서일까요?
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 기본 강의
redux-thunk import error
Attempted import error: 'redux-thunk' does not contain a default export (imported as 'thunk').ERROR in ./src/index.js 16:69-74export 'default' (imported as 'thunk') was not found in 'redux-thunk' (possible exports: thunk, withExtraArgument) 이런 오류가 뜨는데 어떻게 해결해야하는걸까요?? import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import { Provider } from 'react-redux'; import DatePicker from 'antd'; import { applyMiddleware, createStore } from 'redux'; import promiseMiddleware from 'redux-promise'; import thunk from 'redux-thunk' import Reducer from './_reducers'; const createStoreWithMiddleware = applyMiddleware(promiseMiddleware, thunk)(createStore) const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <Provider store={createStoreWithMiddleware(Reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() )}> <App /> </Provider> ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
짹짹 버튼 클릭시 게시물을 우측이 아닌 아래로 정렬하는 방법
질문)짹짹을 눌렀을 때 게시물이 우측에 정렬되는데 어떻게 해야 아래로 정렬될까요? 현재 게시물 추가시 화면)작성한 코드)PostForm.jsimport React,{useCallback, useState, useRef} from 'react'; import {Form, Input, Button} from 'antd'; import {useSelector, useDispatch} from 'react-redux'; import {addPost} from '../reducers/post'; const PostForm = () => { const {imagePaths} = useSelector((state) => state.post); const dispatch = useDispatch(); const imageInput = useRef(); const [text, setText] = useState(''); const onChangeText = useCallback((e) => { setText(e.target.value); }, []) const onSubmit = useCallback(()=> { dispatch(addPost); setText(''); }); const onClickImageUpload = useCallback(() => { imageInput.current.click(); }, [imageInput.current]); return ( <Form style={{ margin: '10px 0 20px'}} encType="multipart/form-data" onFinish={onSubmit}> <Input.TextArea value={text} onChange={onChangeText} maxLength={140} placeholder="어떤 신기한 일이 있었나요?" /> <div> <input type="file" multiple hidden ref={imageInput}/> <Button onClick={onClickImageUpload}>이미지 업로드</Button> <Button type="primary" style={{float:'right'}} htmlType="submit">짹짹</Button> </div> <div> {imagePaths.map((v) => ( <div key={v} style={{display: 'inline-block'}}> <img src={v} style={{width:'200px'}} alt={v}/> <div> <Button>제거</Button> </div> </div> ))} </div> </Form> ) } export default PostForm;post.jsexport const initalState = { mainPosts:[{ id:1, User:{ id:1, nickname: '해지니1', }, content: '첫 번째 게시글 #해시태그 #행복한집사생활', Images:[{ src: 'https://loremflickr.com/640/360' },{ src: 'https://placekitten.com/640/360' },{ src: 'https://picsum.photos/640/360' }], Comments: [{ User: { nickname:'해지니2' }, content: '고양이는 다 기여벙', }, { User: { nickname:'해지니3' }, content: '냥냥냥' }] }], imagePaths: [], //게시물 저장 경로 postAdded: false //게시글 추가 완료시 true } const ADD_POST = 'ADD_POST'; export const addPost = { type: ADD_POST } const dummyPost = { id: 2, content: '더미데이터', User: { id:1, nickname:'해지니', }, Images: [], Comments: [], }; const reducer = (state = initalState, action) => { switch(action.type){ case ADD_POST: return { ...state, mainPosts: [dummyPost, ...state.mainPosts], postAdded: true, }; default: return state; } } export default reducer;
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
cors 설정에도 불구하고 405 에러 스프링부트 3.16
안녕하세요 영상강의를 보며 클론 코딩하면서 하나씩 배우고 있는데백단에서 Cors 설정을 해주었음에도 불구하고 (강의 섹션 3 수정/삭제 처리 진행 중 )@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowedMethods("HEAD", "GET", "POST", "PUT", "DELETE", "OPTIONS").maxAge(300).allowedHeaders("Authorization", "Cache-Control", "Content-Type");}여전히 호출 불가 상태로 있는데 원인을 모르겠습니다. 혹시나 몰라 todoApi.js 파일을 제공된 소스파일로 엎어쳐서 진행을 했는데도 불구하고 말이죠..
-
미해결웹 게임을 만들며 배우는 React
useInterval.js 커스텀 훅에서, 왜 첫번째 useEffect를 계속 반복해야할까요?
안녕하세요 제로초님. 리액트 강의 언제나 잘 듣고 있습니다. 양질의 강의 너무 감사합니다. 제로토님의 '커스텀 훅으로 우아하게 인터벌하기' 강의를 듣고 난 후 개인적으로 코드를 분석해보고 있었는데, 공식 문서도 찾아보고 개인적으로 테스트를 굴려봐도 해결되지 않는 의문이 있어 찾아왔습니다. 먼저, 함수 컴포넌트 파일에서 아래 <1번> 처럼 구성하였기 때문에, 변수 changeHand에는 모양만 같을 뿐 저장공간이 다른 새로운 함수가 매 랜더링 시 마다 만들어진 후 useInterval에 매개변수로 넘어가겠구나.. 하고 이해했습니다. <1번> const changeHand = () => { console.log(imgCoord); if (imgCoord===rspCoords.r) { setImgCoord(rspCoords.s); } else if (imgCoord === rspCoords.s) { setImgCoord(rspCoords.p); } else if (imgCoord === rspCoords.p) { setImgCoord(rspCoords.r); } } useInterval(changeHand, isRunning ? 100 : null); 그리고 useInterval 함수와 아래 <2번> 코드가 컴포넌트가 새로 랜더링 될 때 마다 실행 될 것이라고도 이해했습니다. <2번> useEffect(()=>{ savedCallback.current = callback; }); 그러니 즉, 아래 두 코드를 해석해보자면 매 랜더링 시 마다 새로운 changeHand 함수를 만들어, useInterval을 호출해 매개변수로 넘겨준 다음 useRef 훅으로 saveCallback.current에 저장해주고 있다.. 라고 이해했습니다. (잘 이해한게... 맞을까요..?) 그리고 이렇게 저장된 changeHand 함수는 <3번> 코드의 setInterval(tick, delay)에 의해, delay초 마다 한번씩 실행되게 된다는 내용 까지 이해했습니다. <3번> useEffect(()=>{ function tick() { savedCallback.current(); } if (delay !== null) { let id = setInterval(tick, delay); return () => { clearInterval(id);} } }, [delay]); 일단 저는 '왜 첫번째 useEffect(2번 코드)를 계속 반복해야할까요?' 라는 질문의 답에 대해서, 매 랜더링 시 마다 컴포넌트와 컴포넌트 함수들은 새로이 만들어지기 때문에, 마찬가지로 savedCallback에도 이전 함수가 아니라 새로 만들어진 함수를 저장해야하기 때문이겠구나.. 라고 생각했었습니다. 하지만 이 가정이 맞다면, 컴포넌트가 재실행되며 이전 컴포넌트 객체였던 것은 생명주기 순서에 따라 새로 랜더링 되기 전에 삭제될 테니, 이전 컴포넌트 객체와 함수들은 저장공간에 남아있지 말아야 할 것입니다. 그래서 별도로 배열 변수를 만들어, 랜더링 시 마다 만들어지는 changeHand 함수를 순서대로 저장한 후 한 20번 째 랜더링 쯤에서 두 번째로 만들어진 changeHand 함수를 콘솔창에 찍어봤었습니다. 저는 이 과정을 통해 undefind 에러가 발생하거나 null값이 출력될 줄 알았는데(더이상 메모리에 없는 함수 객체일테니..) 잘만 실행되더군요 ㅠㅠㅠ 제가 어떤 부분을 이해하지 못하고 있는 걸까요..? (아예 통째로 잘못 이해하고 있는 것도 같고... ㅠㅠ) 감사합니다.
-
해결됨Next + React Query로 SNS 서비스 만들기
signup redirect error
섹션4 2번째 강의 내용입니다.회원가입 진행시에 home으로 redirect 되지 않아 문제를 파악중에 네트워크탭에서 대기중인 상태가 지속되는 것을 확인했습니다.db에는 user data가 정상적으로 들어온 것을 확인했습니다.어디 잘못된 부분이 있나 싶어 강사님 코드를 그대로 복사해서 다시 실행 해 보았지만 안되고 있는데 혹시 짐작 가시는 부분 잇으실까요. 회원가입 버튼을 누른후에 x 버튼도 되지 않고 있습니다.
-
미해결Next + React Query로 SNS 서비스 만들기
server action과 useState에 관해 질문드립니다!
안녕하세요 제로초님 소중한 강의 감사히 보고있습니다.다름이 아니라 강의를 잘 이해하다가 Server action 부터 잘 와닿지가 않아서 질문드립니다.SignupModal.tsx 를 server component로 변경하는 과정을 보고있는데요.리액트에서는 input 태그의 입력값을 useState와 onChange로 관리하지 하지 않으면, "A component is changing an uncontrolled input to be controlled" 와 같은 에러를 띄웠기 때문에 모든 input 값은 useState를 통해 관리하는게 바람직하다고 생각해왔습니다. 리액트 기반으로 동작하는 next도 당연히 그럴 줄 알았습니다.그런데 센세이셔널하게 server action에서 그게 통째로 사라져 버리니 매우 혼란스럽습니다. 단지 서버 컴포넌트로 바뀌었기 때문에 없어져도 상관없는건가요?input태그 입력은 데이터가 실시간으로 입력되는 과정이니까 클라이언트 컴포넌트에서 이루어지는게 맞다고 생각을 해와서그런지 쉽게 받아들여지지 않습니다.또한 말씀하신 방법을 사용했을 때, 만약 입력값 유효성 검사에 있어서 단순히 입력 유무를 확인하는 required 속성 말고도, 입력값을 실시간으로 체크해 유효성 검사 결과를 로직(ex) '사용할 수 있는/없는 비밀번호입니다'를 실시간으로 보여주는 helperText )같은 경우는 구현이 불가능한게 되는 것인지 궁금합니다.모든 컴포넌트를 다 sever action을 활용하는 방식으로 바꾼다면, useState는 사용될 일이 거의 없어지는 건가요..?
-
미해결웹 게임을 만들며 배우는 React
2-9. 웹팩 데브 서버와 핫 리로딩 6:16부분
리로딩과 핫리로딩의 차이를 설명하신 부분에서 핫리로딩은 기존 데이터를 유지한다고 하셨습니다. 그래서 저는 핫리로딩은 새로고침 없이 변경사항이 저장된다고 생각했는데 react-refresh 플러그인을 넣으나 안 넣으나 새로고침 되는건 같고 끝말잇기 프로젝트 내에서 데이터도 모두 초기화가 되었습니다. 그래서 현재 강의 내용으로는 핫리로딩과 리로딩의 차이를 명확히 알 수 없는데 부가적인 설명과 예시 부탁드립니다!