묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
10-08 숙제 정답 질문입니다.
타입 문제라고 해서 dto랑 product.entity에 타입이 서로 각각string[] , ProductTag[] 로 서로 다른 타입으로 설정 했더라구요 그래서 그냥 똑같이 ProductTag[] 으로 똑같이 설정 했더니 오류는 사라졌습니다 근데 이게 정답이 맞나요? 수정 전 dto @Field(() => [String]) productTags: string[]; product.entity.ts @Field(() => [ProductTag]) productTags: ProductTag[]; 수정후 dto @Field(() => [ProductTag]) productTags: ProductTag[];
-
미해결코로나맵 개발자와 함께하는 지도서비스 만들기 2
marker 크기 관련 질문
안녕하세요. 강의를 듣고 있는 고등학생입니다. 학교 프로젝트로 강의 하천이나 수질을 나타내는 지도 서비스를 만들려고 하는데 강의 길이에 따라 마커의 크기를 바꾸고 강의 수질에 따라 마커의 색을 바꾸고 싶습니다. css 파일 자체에서 index.js에서 선언된 변수에 따라 마커의 크기를 바꿀 수는 없나요??
-
해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
css 파일 작성시 > 표시 여부
안녕하세요. 투두리스트 ui 구현 중 질문이 생겨 댓글 남깁니다"Header.css" 파일은 h1 태그에 접근 시 ".Header > h1" 과 같이 > 표시를 사용하는데"Editor.css" 파일은 > 표시 없이 그냥 ".Editor input" 로 작성하시더라구요이 둘의 차이가 뭔가요?좋은 강의와 친절한 답변 항상 감사드립니다 :) 🚨 아래의 가이드라인을 꼭 읽고 질문을 올려주시기 바랍니다 🚨질문 하시기 전에 꼭 확인해주세요- 질문 전 구글에 먼저 검색해보세요 (답변을 기다리는 시간을 아낄 수 있습니다)- 코드에 오타가 없는지 면밀히 체크해보세요 (Date와 Data를 많이 헷갈리십니다)- 이전에 올린 질문에 달린 답변들에 꼭 반응해주세요 (질문에 대한 답변만 받으시고 쌩 가시면 속상해요 😢)질문 하실때 꼭 확인하세요- 제목만 보고도 무슨 문제가 있는지 대충 알 수 있도록 자세한 제목을 정해주세요 (단순 단어 X)- 질문의 배경정보를 제공해주세요 (이 문제가 언제 어떻게 발생했고 어디까지 시도해보셨는지)- 문제를 재현하도록 코드샌드박스나 깃허브 링크로 전달해주세요 (프로젝트 코드에서 문제가 발생할 경우)- 답변이 달렸다면 꼭 확인하고 반응을 남겨주세요- 강의의 몇 분 몇 초 관련 질문인지 알려주세요!- 서로 예의를 지키며 존중하는 문화를 만들어가요. - 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
로컬스토리지
import { Route, Routes } from "react-router-dom"; import { useReducer, useRef, createContext, useEffect, useState } from "react"; import Home from "./pages/Home"; import New from "./pages/New"; import Diary from "./pages/Diary"; import Notfound from "./pages/Notfound"; import Edit from "./pages/Edit"; const mockData = [ { id: 1, createdDate: new Date("2024-10-01").getTime(), emotionId: 1, content: "1번일기 내용", }, { id: 2, createdDate: new Date("2024-10-10").getTime(), emotionId: 2, content: "2번일기 내용", }, { id: 3, createdDate: new Date("2024-09-09").getTime(), emotionId: 3, content: "3번일기 내용", }, { id: 4, createdDate: new Date("2024-10-04").getTime(), emotionId: 3, content: "3번일기 내용", }, ]; function reducer(state, action) { let nextState; switch (action.type) { case "INIT": { return action.data; } case "CREATE": { nextState = [...state, action.data]; break; } case "UPDATE": { nextState = state.map((item) => item.id === action.data.id ? action.data : item ); break; } case "DELETE": nextState = state.filter((item) => item.id !== action.id); break; default: return state; } localStorage.setItem("diary", JSON.stringify(nextState)); return nextState; } export const DiaryStateContext = createContext(); export const DiaryDispatchContext = createContext(); function App() { const [isLoading, setIsLoading] = useState(true); const [data, dispatch] = useReducer(reducer, []); const idRef = useRef(0); useEffect(() => { const storedData = localStorage.getItem("diary"); if (!storedData) { setIsLoading(false); return; } const persedData = JSON.parse(storedData); if (!Array.isArray(persedData)) { setIsLoading(false); return; } let maxId = 0; persedData.forEach((item) => { if (Number(item.id) > maxId) { maxId = Number(item.id); } }); idRef.current = maxId + 1; dispatch({ type: "INIT", data: persedData, }); setIsLoading(false); }, []); const onCreate = (createdDate, emotionId, content) => { dispatch({ type: "CREATE", data: { id: idRef.current++, createdDate, emotionId, content, }, }); }; if (isLoading) { return <div>데이터 로딩중입니다...</div>; } const onUpdate = (id, createdDate, emotionId, content) => { dispatch({ type: "UPDATE", data: { id, createdDate, emotionId, content, }, }); }; const onDelete = (id) => { dispatch({ type: "DELETE", id, }); }; return ( <> <DiaryStateContext.Provider value={data}> <DiaryDispatchContext.Provider value={{ onCreate, onUpdate, onDelete }}> <Routes> <Route path="/" element={<Home />} /> <Route path="/new" element={<New />} /> <Route path="/diary/:id" element={<Diary />} /> <Route path="/edit/:id" element={<Edit />} /> <Route path="*" element={<Notfound />} /> </Routes> </DiaryDispatchContext.Provider> </DiaryStateContext.Provider> </> ); } export default App; 질문폭탄 죄송합니다ㅠㅠㅠ 왜 저는 새로고침하면 빈배열로 화면에 나타날까요? 로컬스토리지에 저장은 되더라구요그리고 let nextState; 이렇게 저장하면 state값이 바뀔 때 nexState도 초기화 되지 않나요? 초기화 되고 나서 값을 저장한 후 사용해서 상관이 없는건가요?
-
해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
undefined일 경우
const Diary = () => { const params = useParams(); const nav = useNavigate(); const currentDiaryItem = useDiary(params.id); if (!currentDiaryItem) { return <div>데이터로딩중</div>; } const { createdDate, emotionId, content } = currentDiaryItem; const Edit = () => { const nav = useNavigate(); const { onDelete, onUpdate } = useContext(DiaryDispatchContext); const params = useParams(); const currentDiaryItem = useDiary(params.id);Diary컴포넌트와 Edit컴포넌트 둘 다 useDiary로부터 currentDiaryItem을 받아오고 있는데, Diary는 undefined일 때경우를 처리해주고 있는데, Edit컴포넌트는 그렇지 않습니다. useEffect(() => { if (initData) { // undefined일 때 setInput({ ...initData, createdDate: new Date(Number(initData.createdDate)), }); } }, [initData]);위코드는 Editor컴포넌트 안의 코드입니다. 여기서 undefined룰 걸려주기 때문에 Edit컴포넌트에서 처리를 안해도 되는 건가용?
-
해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
Diary.jsx
import { useContext, useState, useEffect } from "react"; import { DiaryStateContext } from "../App"; import { useNavigate } from "react-router-dom"; const useDiary = (id) => { const data = useContext(DiaryStateContext); const [currentDiaryItem, setCurrentDiaryitem] = useState(); const nav = useNavigate(); useEffect(() => { const currentDiaryItem = data.find( (item) => String(item.id) === String(id) ); if (!currentDiaryItem) { window.alert("존재하지 않는 일기입니다."); nav("/", { replace: true }); } setCurrentDiaryitem(currentDiaryItem); }, [id, data]); //data는 왜쓰는지? return currentDiaryItem; }; export default useDiary; 강의 내용코드입니다. 현재의 일기를 가져오는 커스텀훅입니다.여기서 문제는 "존재하지 않는 일기입니다"라는 경고창이 2번뜹니다. http://localhost:5173/diary/1234 처럼 아무숫자나 입력했을 때 그리고 http://localhost:5173/ 으로 이동한 후에 경고창이 한번 더 뜹니다. useEffect가 id가 변함에 따라 계속 실행되어서라는 이유로 알고 있습니다. 그러면 왜 선생님코드에서는 경고창이 2번 뜨지 않았을까용?그리고 의존성 배열에 [id, data] 2가지를 담는 이유가 궁금합니다. 현재 prams.id가 바뀔 때만 작동하게 해도 되지 않을까요? 사용자가 data를 수정하면서 페이지의 파라미터가 바뀌는 상황이 동시에 일어나지 않을 거 같아서요
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
does not provide an export named 'userReducer'
does not provide an export named 'userReducer'라는 에러가 뜹니다.맞게 작성한거 같은데...설정을 잘못했을까요?
-
해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
new Date()
const Editor = ({ onSubmit, initData }) => { const nav = useNavigate(); const [input, setInput] = useState({ createdDate: new Date(), // 여기서 그냥 getTime하면 안되나요? emotionId: 8, content: "", }); useEffect(() => { if (initData) { setInput({ ...initData, createdDate: new Date(Number(initData.createdDate)), }); } input의 createdDate와 initData의 createdDate 비교 기준이 new Date()과 new Date().getTime() 로 달라서 useEffect안에서 createdDate: new Date(Number(initData.createdDate)), 이렇게 한다는 건 이해가 갑니다. 다만 처음부터 input의 createdDate를 new Date().getTime()으로 만들면 되지 않을까요?
-
미해결코로나맵 개발자와 함께하는 지도서비스 만들기 2
upload.css 관련 질문
body { padding: 0px !important; margin: 0px !important; font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; } a { color: #00B7FF; } ul { list-style-type: none; margin: 0px; padding: 0px; overflow: hidden; background: #333; position: fixed; width: 100%; z-index: 1001; } li { float: left; } li a { display: block; color: white; text-decoration: none; text-align: center; padding: 14px 16px; } .active { background-color: #0322AB; } li a:hover:not(.active) { background-color: #111; } .infow .body { position: relative; overflow: hidden; } .info .desc { position: relative; margin: 8px 0 0 90px; height: 75px; display: block; } .map .wrap, .map_wrap * { margin: 0; padding: 0; font-size: 12px; } #menu_wrap { position: absolute; top: 0; left: 0; bottom: 0; width: 200px; margin: 50px 0 30px 10px; padding: 5px; overflow-y: auto; background: rgba(255, 255, 255, 0.7); z-index: 1; font-size: 12px; border-radius: 10px; } #menu_wrap hr { display: block; height: 1px; border: 0; border-top: 2px solid #5f5f5f; margin: 3px 0; } #placesList .item { position: relative; border-bottom: 1px solid #888; overflow: hidden; cursor: pointer; width: 100px; } #placesList .item span { display: block; margin-top: 4px; } #placesList .item .info { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; padding: 20px; } #placesList .item .active .info_title { font-weight: bolder; }인포윈도우에서 제목에 볼드 처리가 되지 않고, 검색결과 간의 구분이 표시되지 않습니다...
-
미해결코로나맵 개발자가 알려주는 React + Express로 지도서비스 만들기 (Typescript)
보일러플레이트 코드 오류
보일러플레이트 코드 수업 자료 관련해서 다운받았는데 빈폴더라고 저번 질문에 문의드렸는데 사용중인 os만 물어보시고 답변이 없으셔서 다시 질문드려요 사용중인 os는 윈도우입니다.
-
미해결코로나맵 개발자와 함께하는 지도서비스 만들기 2
mongoDB 관련 질문
#!/usr/bin/env node /** * Module dependencies. */ var app = require('../app'); var debug = require('debug')('suzil:server'); var http = require('http'); const mongoose = require("mongoose"); const userConfig = require("../config/userConfig.json"); let db = mongoose.connection; db.on("error",console.error); db.once("open",()=>{ console.log("Connected to mongo Server"); }); mongoose.connect( `mongodb+srv://wiyuchan1021:${userConfig.PW}>@suzilo.i1je5.mongodb.net/suzilo?retryWrites=true&w=majority`, {useNewUrlParser: true, useUnifiedTopology: true} ) /** * Get port from environment and store in Express. */ var port = normalizePort(process.env.PORT || '3000'); app.set('port', port); /**f * Create HTTP server. */ var server = http.createServer(app); /** * Listen on provided port, on all network interfaces. */ server.listen(port); server.on('error', onError); server.on('listening', onListening); /** * Normalize a port into a number, string, or false. */ function normalizePort(val) { var port = parseInt(val, 10); if (isNaN(port)) { // named pipe return val; } if (port >= 0) { // port number return port; } return false; } /** * Event listener for HTTP server "error" event. */ function onError(error) { if (error.syscall !== 'listen') { throw error; } var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } /** * Event listener for HTTP server "listening" event. */ function onListening() { var addr = server.address(); var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); } 코드 실행하면PS C:\Users\yuchan\suzil> npm start> suzil@0.0.0 start> nodemon ./bin/www[nodemon] 3.1.7[nodemon] to restart at any time, enter rs[nodemon] watching path(s): .[nodemon] watching extensions: js,mjs,cjs,json[nodemon] starting node ./bin/www(node:13580) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version (Use node --trace-warnings ... to show where the warning was created)(node:13580) [MONGODB DRIVER] Warning: useUnifiedTopology is a deprecated option: useUnifiedTopology has no effect since Node.js Driver version 4.0.0 and will be removed in the next major versionMongoServerError: bad auth : authentication failed at Connection.sendCommand (C:\Users\yuchan\node_modules\mongodb\lib\cmap\connection.js:289:27) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Connection.command (C:\Users\yuchan\node_modules\mongodb\lib\cmap\connection.js:312:26) at async continueScramConversation (C:\Users\yuchan\node_modules\mongodb\lib\cmap\auth\scram.js:131:15) at async executeScram (C:\Users\yuchan\node_modules\mongodb\lib\cmap\auth\scram.js:80:5) at async ScramSHA1.auth (C:\Users\yuchan\node_modules\mongodb\lib\cmap\auth\scram.js:39:16) at async performInitialHandshake (C:\Users\yuchan\node_modules\mongodb\lib\cmap\connect.js:104:13) at async connect (C:\Users\yuchan\node_modules\mongodb\lib\cmap\connect.js:24:9) { errorResponse: { ok: 0, errmsg: 'bad auth : authentication failed', code: 8000, codeName: 'AtlasError' }, ok: 0, code: 8000, codeName: 'AtlasError', connectionGeneration: 0, [Symbol(errorLabels)]: Set(2) { 'HandshakeError', 'ResetPool' }}node:internal/process/promises:391 triggerUncaughtException(err, true /* fromPromise */); ^MongoServerError: bad auth : authentication failed at Connection.sendCommand (C:\Users\yuchan\node_modules\mongodb\lib\cmap\connection.js:289:27) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Connection.command (C:\Users\yuchan\node_modules\mongodb\lib\cmap\connection.js:312:26) at async continueScramConversation (C:\Users\yuchan\node_modules\mongodb\lib\cmap\auth\scram.js:131:15) at async executeScram (C:\Users\yuchan\node_modules\mongodb\lib\cmap\auth\scram.js:80:5) at async ScramSHA1.auth (C:\Users\yuchan\node_modules\mongodb\lib\cmap\auth\scram.js:39:16) at async performInitialHandshake (C:\Users\yuchan\node_modules\mongodb\lib\cmap\connect.js:104:13) at async connect (C:\Users\yuchan\node_modules\mongodb\lib\cmap\connect.js:24:9) { errorResponse: { ok: 0, errmsg: 'bad auth : authentication failed', code: 8000, codeName: 'AtlasError' }, ok: 0, code: 8000, codeName: 'AtlasError', connectionGeneration: 0, [Symbol(errorLabels)]: Set(2) { 'HandshakeError', 'ResetPool' }}Node.js v20.17.0[nodemon] app crashed - waiting for file changes before starting...이러한 오류가 터미널에 뜨는데 왜 그런걸까요?
-
해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
input의 value속성이 꼭 필요한가요?
<input value={getStringedDate(input.createdDate)} name="createdDate" onChange={onChange} type="date" className="bg-[rgb(236,236,236)] font-xl rounded-md px-[20px] py-[10px]" /> 새로운 일기를 만들때 날짜 input에서 value속성을 'getStringedDate(input.createdDate)'이렇게 설정하고 있는데요 저는 value속성을 넣지 않고도 작동을 합니다. value속성 꼭 적어야 할까요? 단순히 초기값을 설정하기 위함일까요? 아니라면 value속성을 적는 것이 권장되는 이유는 뭘까용?
-
미해결사물인터넷 통신은 내 손에 (Arduino, MQTT, Nodejs, MongoDB, Android,VS Code)
mongodb 접속 실패
Drivers를 선택해서 나온 url주소로도 MongoDB for VS Code를 선택해서 나온 url주소로도 접속이 실패합니다.Node.js 코드는 다음과 같이 작성했습니다.const mongoose = require("mongoose"); const MONGODB_URL = "mongodb+srv://root:1234@education.sidnf.mongodb.net/"; mongoose .connect(MONGODB_URL) .then(() => console.log("Connected to database!")) .catch(() => console.log("Connection failed..."))Connection failed... 라고 나옵니다.Network Access에서도 0.0.0.0으로도 해보고, 제 컴퓨터의 IP주소로도 해보았습니다.전부 접속 실패가 뜹니다.이유를 알 수 있을까요?!
-
해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
BrowserRouter사용방법
강의 12.3 보다가 의문이 들어서 질문 남깁니다.강의에서 설명하고 사용하셨던 방법과 공식문서에서 BrowserRouter를 사용하는 방법이 달라서 헷갈립니다.두가지 방법이 같은 것인지, 다르다면 어떻게 다른지 알려주세요function App() { return ( <BrowserRouter basename="/app"> <Routes> <Route path="/" /> </Routes> </BrowserRouter> ); }=>공식문서에서는 이렇게 Routes를 BrowserRouter로 감싸서 사용했는데 강의 에서는 그러지 않아서 궁금합니다.!
-
해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
Home page에서 getMonthlyData 함수
const getMonthlyData = (pivotDate, data) => { //컴포넌트 밖에서 함수를 만드는 이유? const beginTime = new Date( pivotDate.getFullYear(), pivotDate.getMonth(), 1, 0, 0, 0 ).getTime(); const endTime = new Date( pivotDate.getFullYear(), pivotDate.getMonth() + 1, 0, 0, 0, 0 ).getTime(); return data.filter( (item) => beginTime <= item.createdDate && item.createdDate <= endTime ); };endtime을 0일 23시 59분 59초가 아닌 0일 0시 0분 0초로 설정해도 될까요? 월에서 +1을 했으니 마지막 일도 포함될 거 같아서요!
-
미해결코로나맵 개발자와 함께하는 지도서비스 만들기 1
호스팅 및 도메인 관련
강의를 통해 만든 웹사이트를 다른 사람들도 이용할 수 있도록 호스팅하는 방법과 도메인을 연결하는 방법은 어떻게 되나요??
-
해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
Editor css justify-content 질문
15:04에 .Editor .emotion_section .emotion_list_wrapper에서 justify-content: space-around;해도 아래 사진과 같이 요소를 화면 중심으로 배치할 수 없어서요. 어떻게 해야하는 건지 답변 부탁드립니다.
-
해결됨[2024] 한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
nav('/', { replace: true }); 뒤로가기 방지
import Header from '../components/Header'; import Button from '../components/Button'; import Editor from '../components/Editor'; import { useNavigate } from 'react-router-dom'; import { useContext } from 'react'; import { DiaryDispatchContext } from '../App'; const New = () => { const nav = useNavigate(); const { onCreate } = useContext(DiaryDispatchContext); const onSubmit = (input) => { onCreate(input.createdDate.getTime(), input.emotionId, input.content); nav('/', { replace: true }); }; return ( <div> <Header title={'새 일기 쓰기'} leftChild={ <Button text={'< 뒤로 가기'} onClick={() => { nav(-1); }} /> } /> <Editor onSubmit={onSubmit} /> </div> ); }; export default New; 여기서 nav('/', {replace:true});로 뒤로가기(New 페이지로 가는 것)를 방지했는데,뒤로가기를 한 번 눌렀을 때는 잘 동작하는데두 번 눌렀을 때부터 뒤로 가집니다. 혹시 원래 이런건가요? 아니면 제가 뭔가 잘못한건가요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
graphql 에 이렇게 뜨는 버그 어떻게 해결할 수 있나요?
원래는 그렇지 않았는데 전부터 graphql 에서 api 테스트 해보려고 하면 아래에 항상 이런방식으로 글자 나타나고 사라지지 않더라고요.. 맥을 사용하고 있는데 이거 어떤 방식으로 해결할 수 있나요?
-
미해결코로나맵 개발자가 알려주는 React + Express로 지도서비스 만들기 (Typescript)
수업자료 오류
보일러플레이트 코드 소개에 있는 수업자료를 다운받았는데 압축해제하려고 보니까 해제도 안되고 압축폴더에는 파일이 아무것도 없네요