묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결한 입 크기로 잘라먹는 Next.js(v15)
next.js에서 로컬스토리지를 사용할 때
안녕하세요! 이정환 강사님.next 강의를 거의 다 수강해가는 것 같아서 배운걸 활용해 혼자 간단한 투두리스트를 구현해보고 있는데요.새로고침 시에도 할일목록이 유지되도록 하기 위해 로컬스토리지에 저장된 목록을 가져오고또 저장하는 로직을 작성하였더니ReferenceError: localStorage is not defined이와 같은 오류를 만나서 useEffect를 사용해서 아래와 같이 작성하였습니다.// useTodo 커스텀 훅 일부 const [todoList, setTodoList] = useState<Todo[]>([]); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const storedTodos = getStoredTodoFromLocalStorage(); setTodoList(storedTodos); setIsLoading(false); }, []); useEffect(() => { if (todoList.length > 0) saveTodoToLocalStorage(todoList); }, [todoList]); // ToDoItemList.tsx export default function ToDoItemList({ isLoading, todoList, toggleTodoCompletion, }: ToDoItemListProps) { if (isLoading) { return <S.ToDoItemList>로딩중...</S.ToDoItemList>; } if (todoList.length === 0) return ( <S.ToDoItemList> <S.EmptyList>할일을 생성해보세요✨</S.EmptyList> </S.ToDoItemList> ); return ( <S.ToDoItemList> {todoList.map(todo => ( <ToDoItem key={todo.id} todo={todo} toggleCompletion={toggleTodoCompletion} /> ))} </S.ToDoItemList> ); }처음엔 로딩상태를 만들지 않고 todolist.length가 0이면 "할일을 생성해보세요"가 보이고아니면 할일 목록을 보여주도록 했습니다.하지만 그렇게 하니까 할일 목록을 작성하고 새로고침을 누르면 "할일을 생성해보세요"가 잠깐 나타나고기존에 작성한 할일 목록이 나타나더라구요... 그래서 로딩중을 추가했는데 이제는 이 투두리스트에 처음 접근한 사람도 아직 아무 데이터도 없는데로딩중이 보이고 할일을 생성해보세요가 나타나게 되는 문제에 직면했습니다.이러한 로직은 어떻게 다루어야 좋을까요?? 제가 의도했던 건처음 투두리스트 작성하려는 유저에겐 "할일을 생성해보세요"가 바로 보이고, 할일을 작성하면 할일목록을, 새로고침을 해도 할일목록을 보여주기이전에 작성한 투두리스트가 있는 유저에겐 할일 목록을 보여주고 새로고침을 해도 그대로 유지해서 보여주기 인데 어떻게 해결할 수 있을지 모르겠습니다...🥲
-
미해결Practical Testing: 실용적인 테스트 가이드
REST Docs 추가 작업중 직렬화,역직렬화 문제
강사님이 기존에 작성해주신 코드들을 가지고 REST Docs를 채워보려고 하고있습니다 !OrderController의 createOrder 메서드에 대해서 테스트 해서 docs를 채워보려고 하는 와중에 LocalDateTime에서 직렬화와 역직렬화 문제가 발생하여서 질문드립니다 ! public class OrderControllerDocsTest extends RestDocsSupport { private final OrderService orderService = mock(OrderService.class); @Override protected Object initController() { return new OrderController(orderService); } @BeforeEach void setUp() { objectMapper.registerModule(new JavaTimeModule()); objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); } @DisplayName("신규 주문을 생성하는 API") @Test void createOrder() throws Exception { OrderCreateRequest request = OrderCreateRequest.builder() .productNumbers(List.of("001", "002")) .build(); List<ProductResponse> productResponses = List.of( ProductResponse.builder() .id(1L) .productNumber("001") .type(HANDMADE) .sellingStatus(SELLING) .name("아메리카노") .price(4000) .build(), ProductResponse.builder() .id(2L) .productNumber("002") .type(HANDMADE) .sellingStatus(HOLD) .name("카페라떼") .price(4500) .build() ); given(orderService.createOrder(any(OrderCreateServiceRequest.class), any(LocalDateTime.class))) .willReturn(OrderResponse.builder() .id(1L) .totalPrice(8500) .registeredDateTime(LocalDateTime.now()) .products(productResponses) .build()); mockMvc.perform( post("/api/v1/orders/new") .content(objectMapper.writeValueAsString(request)) .contentType(MediaType.APPLICATION_JSON) ) .andDo(print()) .andExpect(status().isOk()) .andDo(document("order-create", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), requestFields( fieldWithPath("productNumbers").type(JsonFieldType.ARRAY) .description("상품 번호 리스트") ), responseFields( fieldWithPath("code").type(JsonFieldType.NUMBER) .description("코드"), fieldWithPath("status").type(JsonFieldType.STRING) .description("상태"), fieldWithPath("message").type(JsonFieldType.STRING) .description("메시지"), fieldWithPath("data").type(JsonFieldType.OBJECT) .description("응답 데이터"), fieldWithPath("data.id").type(JsonFieldType.NUMBER) .description("주문 ID"), fieldWithPath("data.totalPrice").type(JsonFieldType.NUMBER) .description("주문 총합 가격"), fieldWithPath("data.registeredDateTime").type(JsonFieldType.STRING) .description("상품 주문 시간"), fieldWithPath("data.products").type(JsonFieldType.ARRAY) .description("상품 판매 목록"), fieldWithPath("data.products[].id").type(JsonFieldType.NUMBER) .description("상품 ID"), fieldWithPath("data.products[].productNumber").type(JsonFieldType.STRING) .description("상품 번호"), fieldWithPath("data.products[].type").type(JsonFieldType.STRING) .description("상품 타입"), fieldWithPath("data.products[].sellingStatus").type(JsonFieldType.STRING) .description("상품 판매 상태"), fieldWithPath("data.products[].name").type(JsonFieldType.STRING) .description("상품 이름"), fieldWithPath("data.products[].price").type(JsonFieldType.NUMBER) .description("상품 가격") ) )); } }이렇게 코드를 작성하니 LocalDateTime을 Array로 만들더라구요 일단 그래서 Array로 해서 반환하니까 물론 테스트는 문제없이 넘어가지만 실제 프로덕션 코드의 Response 코드를 확인해보니 LocalDateTime으로 String으로 넘어가고 있었습니다. 테스트와 실제 프로덕션 코드의 간극이 생기는데 어떻게 해결하면 좋을까요 ? 그리고 기존에 알려주셨던 ProductionControllerDocsTest의 코드를 많이 참고해서 테스트를 작성하였는습니다. 여기서 든 의문점이 이렇게만 작성하면 request와 response만 정의할 뿐 실제로 테스트는 동작하지 않는 것 아닌가 ? 라는 의문이 들었습니다. 실제로 OrderResponse.builder()를 맘대로 바꿔도 테스트가 깨지지않는 상황입니다. 그래서 단순히 Controller단 테스트는 수업때 설명하신 것 처럼 파라미터에 대한 검증만을 하는 것이기 때문에 REST Docs 또한 Request 와 Response의 필드가 어떻게 구성되어있는지 정도만 보여주는 용도로 사용되는건지도 궁금합니다 !
-
해결됨Amazing JavaScript - 입문
코드샌드박스애서 vue강의 따라 코딩하는게 가능할까요?
코드샌드박스애서 vue강의 따라 코딩하는게 가능할까요?npm설치에 문제가 있어서 강의를 못듣고 있거든요
-
미해결SCSS(SASS)+FLEX 실전 반응형 웹 프로젝트 with Figma
[PC 레이아웃 상세 퍼블리싱 - 인클루드] class-detail 에서 인클루드가 작동하지 않아요.
우선, 강의대로 따라했을 때 index.html 에서는 헤더와 푸터 인클루드가 잘됩니다. 따로 test.html 을 만들어서 인클루드 해봐도 잘 됩니다. 하지만 html/class-detail.html 에 인클루드를 하면 헤더와 푸터가 인클루드 되지 않습니다. custom.js 의 경로를 바꿔봐도 안되네요 ㅜㅜ인클루드가 안되는 이유를 알 수 있을까요 ?
-
해결됨인사이드 아웃 본부 만들기 - 블렌더 아이소메트릭
계단 형상 바닥면 평탄화시 모서리 라운드 크기도 작아져요
먼저, 유익한 강의 감사드립니다.!!!계단 경사면 적용 후 바닥면을 평탄화 하려고아래 엣지 선택 후 S - Z - 0 입력하니 계단 형상의 모서리 라운드 크기가 줄어듭니다.※ Scale의 Z 값을 0이 아닌 값(예: 0.1)으로 입력하니 모서리는 줄어들지는 않는데요.제가 뭔가 놓친 부분이 있을까요?
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
페이지 라우터 props질문
페이지 라우터의 경우 props를 통해서 데이터를 받을 수 있다고 하셨는데index파일 부모컴포넌트가 아닌 하위 child 컴포넌트에서는 데이터를 불러올 수 없는 건가요?? 🚨 아래의 가이드라인을 꼭 읽고 질문을 올려주시기 바랍니다 🚨질문 하시기 전에 꼭 확인해주세요- 질문 전 구글에 먼저 검색해보세요 (답변을 기다리는 시간을 아낄 수 있습니다)- 코드에 오타가 없는지 면밀히 체크해보세요 (Date와 Data를 많이 헷갈리십니다)- 이전에 올린 질문에 달린 답변들에 꼭 반응해주세요 (질문에 대한 답변만 받으시고 쌩 가시면 속상해요 😢)질문 하실때 꼭 확인하세요- 제목만 보고도 무슨 문제가 있는지 대충 알 수 있도록 자세한 제목을 정해주세요 (단순 단어 X)- 질문의 배경정보를 제공해주세요 (이 문제가 언제 어떻게 발생했고 어디까지 시도해보셨는지)- 문제를 재현하도록 코드샌드박스나 깃허브 링크로 전달해주세요 (프로젝트 코드에서 문제가 발생할 경우)- 답변이 달렸다면 꼭 확인하고 반응을 남겨주세요- 강의의 몇 분 몇 초 관련 질문인지 알려주세요!- 서로 예의를 지키며 존중하는 문화를 만들어가요. - 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
서버 세팅 문의
안녕하세요 정환님.SSR 개념 강의 이후 실습을 위해서 서버 세팅을 하는 과정 중데이터베이스 스키마 설정하는 부분에서 진행이 되지 않아 문의드립니다.supabase DATABASE_URL 환경변수 설정npx prisma db push 명령어 실행스키마 설정이 진행되지 않음 [버전]prisma: 5.13.0@prisma/client:5.13.0Node.js: 20.11.1
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
2.13) 비동기 작업 처리하기 2. Promise
promise 객체를 어떻게 사용하는건지 배웠는데요콜백지옥을 해결하기 위해 탄생한건가요?promise 객체를 사용해서 비동기함수를 쓰면 얻는 장점이 무엇인가요? 결과적으로 얻는 이점에 대한 설명이 좀 부족하지 않나 싶고 궁금합니다
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
RabbitMQ-service.bat start exited with code 1.
제가 강의를 따라하면서 설치를 잘 못하여서 sc delete RabbitMQ명령어를 사용했고 이후 재설치하여 진행을 하는데 아래와 같이 실패를 하고 있습니다.그래서 호환이 문제이가 싶어서 github에서 버전호환으로 다시 시도를 해도 같은 문제가 발생합니다.RabbitMQ 커멘드로 삭제 다운 실행 관련 명령어를 사용해도 권한 문제가 발생을 했고, 관리자 모드로 명령어를 날려도 권한 문제가 발생했습니다. 혹시 몰라서 cmd 관리자 권한으로 날려도, RabbitMQ-server에 sbin이라는 위치로 들어가서 명령어를 날려도 같습니다.https://stackoverflow.com/questions/16001047/rabbitmq-fails-to-start위 stackoverflow에서 관련 정보를 찾아서 진행을 했는데 같은 문제가 발생 됩니다. 지금 한 3시간 정도 삽질을 하니 진이 빠지네요.. 도와주세욥...
-
해결됨10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트
2-O 문자열 질문드립니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요 ! 강의 도중에 강의 정답에서 입력받은 문자의 끝을 . 로 구분하는 코드가 getline(cin,s) 로 받아서 if (s==".")break; 로 되어 있는데 .일때 break 되면 while 문 박으로 나가게 되는거 아닌가요? 또 "." 로 할때와 '.' 으로 할때의 차이가 궁금합니다.
-
미해결10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트
5-E 시작시간 기준으로 풀어보았는데 왜 틀린지 모르겠습니다.
안녕하세요!강의 잘 듣고 있습니다.제 공부 스타일은 먼저 풀어보고 강의를 듣습니다!일단 강의의 내용은 잘 이해가 되었습니다.하지만 저는 시작을 기준으로 잡고 풀었는데 제 생각에는 예외처리를 잘 해서 문제가 없다고 생각하는데 혹시 뭐가 문제인지 알 수 있을까요?백준 질문게시판에 있는 반례도 다 통과합니다..ㅠㅠhttp://boj.kr/97290f63c432442f952ce3c865ada540
-
미해결Practical Testing: 실용적인 테스트 가이드
강사님이 실무하실 때 어떤 테스트 DB를 사용하시는지 궁금해요
제목 그대로 강사님께서 실무하실 때 어떤 테스트 DB를 사용하지는 지 궁금합니다요강의처럼 h2 in-memory?로컬 DB? (이건 하지 않으실것같아요)테스트 컨테이너?강사님의 경험을 나누어 주세요🙇♂
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
버전 문제일까요?
안녕하세요 4분 45초에ReactDom.create 이렇게 되어있는데 저의 경우createRoot(document.ge로 시작합니다. 구글에 찾아보니 17과 18의 차이라는데https://velog.io/@citron03/React-18%EC%97%90%EC%84%9C-ReactDOM.render%EC%99%80-createRoot그대로 진행해도 문제되지 않을까여 ? 감사합니다.
-
미해결[리뉴얼] 처음하는 MongoDB(몽고DB) 와 NoSQL(빅데이터) 데이터베이스 부트캠프 [입문부터 활용까지] (업데이트)
아나콘다 설치가 어려운데 아나콘다가 꼭 필요 할까요 ?
강의 내용을 듣는데 아나콘다를 필수로 설치 해야 할까요? 아나콘다 없이 강의를 들을 수 있는 방법도 있을까요?
-
해결됨10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트
5-F 질문있습니다 :)
안녕하세요 선생님 🙂 while문을 for문으로 변형해서 풀이해봤는데요, 어느 부분에서 잘못된건지 모르겠어서 질문드립니다.. 항상 감사합니다 :) http://boj.kr/15d96af12b3f4a27bd41562bc6cf4042
-
미해결AWS로 쉽고 빠르지만 아주 견고한 서버 환경을 구축하는 방법
rds 사용자 구성 명령어가 실행이 안되요
영상처럼 시작 템플릿 바꾸고 오토스케일링 그룹 설정 새로운버전으로 바꾸고 로드밸런서 dns 주소로 health체크를 해봤는데 502에러가 뜨고 안되서 여러가지 다 확인해봤는데ec2 만들어지고 git clone 자체가 안되었더라고요 사용자 데이터 명령어 자체가 실행이 안됩니다 직접 들어가서 명령어를 치면 먹습니다 네트워크 문제도아니고 패키지 다운로드 안한것도 아닌데 사용자 데이터 명령어가 git clone 시작도 안되면 어떻게 해결해야될까요? git clone은 되었지만 괜한 root 계정 밑에서만 조회해서 못봤던거... 강사님 해결해주셔서 감사합니다!
-
미해결[2025] 비전공자도 가능한 React Native 앱 개발 마스터클래스
프로젝트 생성에 대해서?
npx react-native init test --version 0.72.6 Expo 아니라면 이렇게 생성해야 하는 거 아닌지요?
-
미해결뉴욕 프로덕트 디자이너가 알려주는, 입문자를 위한 UX디자인 개론
좋은 UX와 안좋은 UX 사례
좋은 강의 감사드립니다.- 좋은 UX의 사례: MockupWorld를 꼽았습니다.Mockup World는 유/무료 목업 자료를 제공하는 사이트입니다.전체적인 디자인이 일관되게 통일되어있어 보는데 편했습니다. 대응의 원리를 잘 적용하여 사용자가 자주 사용하는 search bar를 상단 네비게이션과 같이 두는 것이 아니라 따로 하단에 크게 배치하여 사이트에 들어가자마자 사용자가 바로 검색할 수 있게 유도했다 생각합니다.search bar 하단에는 카테고리 분류를 칩 버튼으로 두어 무료 목업이 필요한 의도가 높은 사용자들이 검색 없이도 원하는 아이템을 찾을 수 있게 해두었습니다. (바로 아래에 광고가 있는 것이 아쉽지만) 이는 의도가 낮은 사용자라 할지라도 둘러볼 가능성을 높일 것이라 생각 됩니다.- 나쁜 UX의 사례: 미리캔버스를 꼽았습니다.미리캔버스는 미리 캔버스는 저작권 없이 디자인 분야를 잘 모르는 사람들도 다양한 템플릿을 제작할 수 있는 사이트입니다. 1. 카테고리를 썸네일을 사용해 공간 차지를 많이 하다 보니 어떤 템플릿이 있는지 한 눈에 보기 힘듭니다. 위의 Mockup world처럼 이미지 없이 칩 버튼을 사용해 사용자가 원하는 템플릿을 한번에 찾을 수 있게 도와주면 좋을 것 같다는 생각을 하게 되었습니다.2. 템플릿 사이즈에 일관성이 없습니다. 이미지도 화려해 눈이 피로하다 느꼈습니다. 템플릿에 대한 타이틀과 어떤 템플릿인지의 대한 설명도 없어 사용자는 직접 눌러보며 알아봐야 합니다. 카드형 UI로 만들어 템플릿에 대한 기본정보를 넣으면 어떨까 하는 생각이 들었습니다.3. 화면에서는 안 나와있지만 '이번 주 인기 카드 뉴스', '이번 주 인기 포스터' 가 하단에 있습니다. 주 단위로 바뀌고, 사용자가 자주 찾는 인기 있는 목록이라면 추천 목록처럼 상단에 있어야 더 적합하다고 생각합니다.강의를 듣기 전에는 막연하게 잘 사용하면 그게 좋은 UX가 아닌가? 라는 생각을 했지만, 강의를 들은 후 UX 디자인의 원리를 통해 어떤 것이 더 사용자에게 사랑 받는 디자인인지 과제를 통해 감을 잡을 수 있었습니다. 좋은 강의 감사드리며 남은 강의도 열심히 수강 하겠습니다. 감사합니다.
-
미해결스프링 기반 REST API 개발
스프링 부트 3버전에서의 실습
스프링 부트 3버전에서의 실습 관련 업데이트는 진행하지않는건가요?
-
미해결처음 만난 리액트(React)
useEffect 중 의존성 배열이 있는 부분 관련 질의
import React, {useState, useEffect} from "react"; import useCounter from "./useCounter"; const MAX_CAPACITY = 10; //최대 카운트 function Accommodate(props){ const [isFull, setIsFull] = useState(false); const [count, increaseCount, decreaseCount] = useCounter(0); useEffect(() => { console.log("===========배열없음"); console.log("useEffect is Called"); console.log(`isFull : ${isFull}`); }); //의존성 배열 없음 useEffect(() => { setIsFull(count >= MAX_CAPACITY); console.log("===========배열있음"); console.log(`Current count value : ${count}`); }, [{count}]); //의존성 배열 있음 return ( <div style={{padding : 16}}> <p>{`총 ${count}명 수용했습니다`}</p> <button onClick={increaseCount} disabled={isFull}>입장</button> <button onClick={decreaseCount}>퇴장</button> {isFull && <p style={{color:"red"}}>정원이 가득찼습니다.</p>} </div> ); } export default Accommodate;import React, { useState } from "react"; //custom Hook //초기 카운트 값을 파라미터로 받아서 카운트라는 이름의 //state를 생성하여 값을 제공하고 증감을 편리하게 할 수 있도록 하는 함수 function useCounter(initialValue){ const [count, setCount] = useState(initialValue); const increaseCount = () => setCount((count) => count+1); const decreaseCount = () => setCount((count) => Math.max(count-1,0)); return [count, increaseCount, decreaseCount]; } export default useCounter;import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import Library from './chapter03_jsx/Library'; //컴포넌트 추가 import Clock from './chapter04_elements/Clock'; import CommentList from './chapter05_component_props/CommentList'; import NotificationList from './chapter06_state/NotificationList'; import Accommodate from './chapter07_hook/Accommodate'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( //<React.StrictMode> <Accommodate /> //</React.StrictMode> ); // 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(); 위와 같이 Accomodate.jsx를 작성했습니다만 정원을 다 채웠을 경우 배열 있음이 한번 더 출력되는 현상이 나왔습니다.의존성 배열이 있는 부분의 ,{count}만 넣으면 오류 워닝이 떠서 배열 취급하기 위해 []를 추가했습니다.[]를 빼고 실행했을 경우 최대 카운트가 먹히지 않아 무한정으로 들어갑니다.제가 뭔가 잘못 한 걸까요?