묻고 답해요
169만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
12.16 Viewer.css background-color 질문
css를 적용하였는데도 감정 이미지의 background가 적용이 되지 않는데 잘못된 것이 있을까요??.Viewer > section{ width:100%; margin-bottom: 100px; display: flex; flex-direction: column; align-items: center; text-align: center; } .Viewer > section > h4{ font-size:22px; font-weight: bold; } .Viewer .emotion_img_wrapper{ width:250px; height:250px; border-radius: 5px; display:flex; flex-direction: column; align-items: center; justify-content: space-around; color: white; font-size: 25px; } .Viewer .emotion_img_wrapper_1{ background-color: rgb(100,201,100); } .Viewer .emotion_img_wrapper_2{ background-color: rgb(157,215,114); } .Viewer .emotion_img_wrapper_3{ background-color: rgb(253,206,23); } .Viewer .emotion_img_wrapper_4{ background-color: rgb(253,132,70); } .Viewer .emotion_img_wrapper_5{ background-color: rgb(253,86,95); }
-
미해결처음 만난 리액트(React)
상태가 업데이트될때 컴포넌트 최상단의 console.log 코드가 두번 실행되는 이유가 궁금합니다.
import React, { useEffect, useState } from "react"; import useCounter from "./useCounter"; const MAX_CAPACITY = 10; export default function Accommodate() { const [isFull, setIsFull] = useState(false); const [count, increaseCount, decreaseCount] = useCounter(0); console.log(count,"rendor Accommodate", new Date().getMilliseconds()) useEffect(() => { console.log("===================="); console.log("useEffect() is called."); console.log("isFull:", isFull); }); useEffect(() => { setIsFull(count >= MAX_CAPACITY); console.log("Current count value:", count); }, [count]) return <> <button onClick={increaseCount}>입장</button> <button onClick={decreaseCount}>퇴장</button> {isFull && <p>정원이 가득 찼습니다.</p>} </>; }안녕하세요! 실습 진행 중에 이해가 안되는 부분이 있어 질문드립니다!우선 컴포넌트 내부에 포함된 state가 변경될때 컴포넌트가 재렌더링 되는게 맞을까요?그게 맞다면, 다음과 같은 순서로 실행된다고 생각했는데요.입장 버튼 클릭increaseCount가 실행되면서 count 상태가 변경됨Accommodate 컴포넌트가 재렌더링첫번째 useEffect함수가 실행두번째 useEffect함수가 실행 그리고 위 순서에 따라 console에는 다음과 같이 출력될 것이라고 예상했는데, 실제로는 캡쳐화면처럼 출력되더라구요.어떤 이유로 컴포넌트 최상단에 있는 console.log(count,"rendor Accommodate", new Date().getMilliseconds()) 코드가 두번 실행되는 건지 이해가 안됩니다.ㅠ제가 놓치고 있는 부분이 많은 것 같은데 어디서 부터 놓친건지 잘 정리가 되지 않네요!ㅠㅠ0 'rendor Accommodate' 991 ==================== useEffect() is called. isFull: false Current count value: 0 1 'rendor Accommodate' 430 ==================== useEffect() is called. isFull: false Current count value: 1
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
그랩마켓 웹화면 구현하기 -2 질문입니다.
header 에서는 header-area를 따로 만들어서 이미지를 관리를 하였는데body에서 배너는 배너-area를 따로 안만들고 바로 banner에 이미지를 넣어서 관리하는 이유가 따로 있나여?? 무슨차이인가요
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
5.4) Props로 데이터 전달하기 Button 추가 시 서버가 응답을 하지 않습니다.
commponents 폴더 하위에 Button.jsx 파일을 만들고 const Button = () => { return <Button>Click</Button>; }; export default Button; 이렇게 입력한 후에 App.jsx에서 import "./App.css"; import Header from "./commponents/Header.jsx"; import Footer from "./commponents/Footer.jsx"; import Main from "./commponents/Main.jsx"; import Button from "./commponents/Button.jsx"; function App() { return ( <> <Button /> <Button /> <Button /> </> ); } export default App; 이렇게 입력하고 새로고침을 하면 계속 이렇게 나오는데 왜 그런걸까요. 🚨 아래의 가이드라인을 꼭 읽고 질문을 올려주시기 바랍니다 🚨질문 하시기 전에 꼭 확인해주세요- 질문 전 구글에 먼저 검색해보세요 (답변을 기다리는 시간을 아낄 수 있습니다)- 코드에 오타가 없는지 면밀히 체크해보세요 (Date와 Data를 많이 헷갈리십니다)- 이전에 올린 질문에 달린 답변들에 꼭 반응해주세요 (질문에 대한 답변만 받으시고 쌩 가시면 속상해요 😢)질문 하실때 꼭 확인하세요- 제목만 보고도 무슨 문제가 있는지 대충 알 수 있도록 자세한 제목을 정해주세요 (단순 단어 X)- 질문의 배경정보를 제공해주세요 (이 문제가 언제 어떻게 발생했고 어디까지 시도해보셨는지)- 문제를 재현하도록 코드샌드박스나 깃허브 링크로 전달해주세요 (프로젝트 코드에서 문제가 발생할 경우)- 답변이 달렸다면 꼭 확인하고 반응을 남겨주세요- 강의의 몇 분 몇 초 관련 질문인지 알려주세요!- 서로 예의를 지키며 존중하는 문화를 만들어가요. - 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
미해결HTML+CSS+JS 포트폴리오 실전 퍼블리싱(시즌2)
목소리 좀 키워주세요.
소리가 너무 작아서 잘 안들립니다..좋은 강의 감사하지만 들을 때마다 볼륨을 거의 최대로 해야 해서 불편한 부분이 있습니다. 소리좀 조금 키워주셨으면 좋겠습니다 ㅠ
-
미해결아바타 커뮤니티앱 만들기 (React Native Expo)
[5-4]글 수정/삭제 기능 구현하기(2) - API연동 부분에서 수정하기 누르면 제목과 내용이 비어있는데요,,, 한번 더 수정하기 눌러야 이전 제목과, 내용이 나옵니다...
import CustomButton from "@/components/CustomButton"; import DescriptionInput from "@/components/DescriptionInput"; import TitleInput from "@/components/TitleInput"; import { ImageUri } from "@/types"; import { router, useLocalSearchParams, useNavigation } from "expo-router"; import { useEffect } from "react"; import { FormProvider, useForm } from "react-hook-form"; import { StyleSheet,View } from "react-native"; import { KeyboardAwareScrollView } from "react-native-keyboard-aware-scroll-view"; import useGetPost from "@/hooks/queries/useGetPost"; import useUpdatePost from "@/hooks/queries/useUpdatePost"; type FormValues= { title:string; description: string; imageUris:ImageUri[]; }; export default function PostUpdateScreen () { const {id} = useLocalSearchParams(); const navigation = useNavigation(); const {data:post} = useGetPost(Number(id)); const updatePost = useUpdatePost(); const postForm = useForm<FormValues>({ defaultValues:{ title:post?.title, description:post?.description, imageUris:post?.imageUris, }, }); const onSubmit = (formValues: FormValues)=> { updatePost.mutate({ id: Number(id), body: formValues, },{ onSuccess:() => router.back(), } ); }; useEffect(()=>{ navigation.setOptions({ headerRight:() => ( <CustomButton label="저장" size="medium" variant="standard" onPress={postForm.handleSubmit(onSubmit)} /> ), }); },[]); return( <FormProvider {...postForm}> <KeyboardAwareScrollView contentContainerStyle={styles.container}> <TitleInput /> <DescriptionInput /> </KeyboardAwareScrollView> </FormProvider> ); } const styles = StyleSheet.create({ container:{ margin:16, gap:16, }, });
-
미해결Vue 3 시작하기
로컬이 안뜹니다..
로컬 화면이 강사님과 동일하게 뜨지 않는데.. 어떻게 하면 될까요..?
-
해결됨React, Node.js, MongoDB로 만드는 나만의 회사 웹사이트: 완벽 가이드
req.cookies.token == undefined 현상
logout을 해보니 400BadRequest:이미 로그아웃 됨 상태가 지속됩니다. console.log(req.cookies.token); 출력해보니 undefined 라고 출력됩니다. 쿠키를 제대로 읽지 못하는것 같은데 왜 이런 현상이 뜨는지 궁금합니다.. const express = require("express"); const router = express.Router(); const bcrypt = require("bcrypt"); const User = require("../models/User"); const axios = require("axios"); const jwt = require("jsonwebtoken"); router.post("/signup", async (req, res) => { try { const { username, password } = req.body; const existingUser = await User.findOne({ username }); if (existingUser) { return res.status(400).json({ message: "이미 존재하는 사용자입니다." }); } const hashedPassword = await bcrypt.hash(password, 10); const user = new User({ username, password: hashedPassword, }); await user.save(); res.status(201).json({ message: "회원가입이 완료되었습니다." }); } catch (error) { res.status(500).json({ message: "서버 오류가 발생했습니다." }); console.log(error); } }); router.post("/login", async (req, res) => { try { const { username, password } = req.body; const user = await User.findOne({ username }).select("+password"); //왜인지 password가 select되지 않아서 추가함 if (!user) { return res.status(401).json({ message: "존재하지 않는 사용자입니다." }); } if (!user.isActive) { return res.status(401).json({ message: "비활성화된 사용자입니다." }); } if (user.isLoggedIn == true) { return res.status(401).json({ message: "이미 접속 중인 사용자입니다." }); } const isValidPassword = await bcrypt.compare(password, user.password); //비밀번호 비교 if (!isValidPassword) { user.failedLoginAttempts += 1; user.lastLoginAttempt = new Date(); if (user.failedLoginAttempts >= 5) { user.isActive = false; //다섯번 틀리면 계정 비활성화 ㅋㅋ await user.save(); return res.status(401).json({ message: "비밀번호를 5회 이상 틀려 계정이 비활성화되었습니다.", }); } await user.save(); return res.status(401).json({ message: "비밀번호가 일치하지 않습니다.", remainingAttempts: 5 - user.failedLoginAttempts, }); } user.failedLoginAttempts = 0; user.lastLoginAttempt = new Date(); user.isLoggedIn = true; try { const response = await axios.get("https://api.ipify.org?format=json"); //공공장소 사용금지요 const ipAddress = response.data.ip; //한번 정제함 user.lastLoginIp = ipAddress; } catch (error) { console.log("IP 주소를 가져오는데 실패했습니다: ", error.message); } await user.save(); const token = jwt.sign( { userId: user._id, username: user.username }, process.env.JWT_SECRET, { expiresIn: "24h" } //토큰 만료는 24시간 ); console.log(token); //오 된다 res.cookie("token", token, { httpOnly: true, //자바스크립트에서 쿠키 접근 불가 secure: "production", //https에서만 쿠키 전송 sameSite: "strict", //같은 사이트에서만 쿠키 전송 maxAge: 24 * 60 * 60 * 1000, //24시간 }); const userWithoutPassword = user.toObject(); //구글링 해보니 이렇게 하면 문서 타입을 일반 객체로 변환할 수 있다고 한다 delete userWithoutPassword.password; //보안때문에 비밀번호는 삭제할 수 있다고 한다 res.json({ user: userWithoutPassword }); } catch (error) { console.log("서버 오류: ", error); res.status(500).json({ message: "서버 오류가 발생했습니다." }); } }); router.post("/logout", async (req, res) => { console.log(req.cookies.token); try { const token = req.cookies.token; if (!token) { return res.status(400).json({ message: "이미 로그아웃된 상태입니다." }); } try { const decoded = jwt.verify(token, process.env.JWT_SECRET); const user = await User.findById(decoded.userId); if (user) { user.isLoggedIn = false; await user.save(); } } catch (error) { console.log("토큰 검증 오류: ", error.message); } res.clearCookie("token", { httpOnly: true, secure: "production", sameSite: "strict", }); res.json({ message: "로그아웃되었습니다." }); } catch (error) { console.log("로그아웃 오류: ", error.message); res.status(500).json({ message: "서버 오류가 발생했습니다." }); } }); router.delete("/delete/:userId", async (req, res) => { try { const user = await User.findByIdAndDelete(req.params.userId); if (!user) { return res.status(404).json({ message: "사용자를 찾을 수 없습니다." }); } res.json({ message: "사용자가 성공적으로 삭제되었습니다." }); } catch (error) { res.status(500).json({ message: "서버 오류가 발생했습니다." }); } }); module.exports = router;
-
해결됨아바타 커뮤니티앱 만들기 (React Native Expo)
[5-4]글 수정/삭제 기능 구현하기(2) - API연동 부분에서 수정하기 누르면 제목과 내용이 비어있는데요,,, 한번 더 수정하기 눌러야 이전 제목과, 내용이 나옵니다...
수정하기 누르면 한번에 바로 ,이전 제목과 내용이 바로 나오는게 아니고;빈상태로 나오다가, 한번더 수정하기 눌러야 이전 제목과 내용이 나오더라구요;; 한번에 바로 나오게하는 방법은 없을까요?
-
해결됨[CSS&JS Master] - 트렌디한 감정기록 일기장 만들기
일기만들기는 혼자만들어야하나요?
일기만들기는 따로 강의가없고 알아서 만드는건가요?
-
미해결처음 만난 리액트(React)
npx create-react-app my-app 명령어 입력이 잘못된 것 같습니다
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.vs code에서 터미널을 열어 바로 입력하였는데 이런 창이 뜹니다. 어떻게 해결할 수 있을까요?
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
오류 함수
이 빨간색은 왜 뜨는걸까요?
-
해결됨[코드캠프] 시작은 프리캠프
과제 profile 부분 질문
폰트 간격 어떻게 띄워요?
-
해결됨[코드캠프] 시작은 프리캠프
과제 Profile 부분 질문
이렇게 하나하나 나눠서 한다고 틀린건아니지만어차피 같은 css속성이고 문서길이만 길어질 뿐이라서과제 레퍼런스에서는<div class="profile_detail> 이렇게 하나로 묶은건가요? 만약에 phone부분만 특정스타일 부여하고 싶으면id부여해주면되는건가요?
-
해결됨한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
TodoList 최적화 질문드립니다.
Editor.jsx 파일은 Props 가 없고단순히 export default memo(editor) 코드만 있으니 당연히 리렌더링이 안되어야 하지만리렌더링이 되고 있습니다.그래서 App.jsx 파일에서<TodoDispatchContext.Provider value={memoizedDispatch}> <Editor /> <List /></TodoDispatchContext.Provider>이렇게 리턴하는걸 <Editor />를 위쪽으로 빼면리렌더링이 안 일어 납니다.dispatchContext 안쪽으로 editor 컴포넌트가 들어가면리렌더링 일어나고 바깥으로 빼면 리렌더링 안 일어 나는거 설명좀 될까요?
-
해결됨React, Node.js, MongoDB로 만드는 나만의 회사 웹사이트: 완벽 가이드
npm run dev 무한로딩
npm run dev를 통해 frontend 폴더에서 다음과같이 정상적으로 실행이 되었습니다.다만, 막상 해당 경로로 접속하면 우외같이 무한로딩에 빠져서 아무것도 뜨지 않습니다.F12 개발자도구로 봐도 어떠한 콘솔에러메시지도 없습니다. 어떻게 해결해야 할까요?
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
To-do list 강의 세션에서 궁금한게 있습니다.
선생님 궁금한 게 있어서 글을 남겨봅니다 오늘 To-do list 강의 세션을 완강했는데 이해를 하지 못하는 부분이 있었습니다 const onUpdate = (targetId) => { setTodo( todo.map((it) => it.id === targetId ? { ...it, isDone: !it.isDone } : it ) ); };onUpdate 부분을 만들때 todo.map((it) => it.id === targetId ? { ...it, isDone: !it.isDone } : it 이분에서 ...it : !it.isDone 이 무엇을 의미하는지와 스프레드 연산자를 쓴 이유를 이해하기 어려웠습니다 const onDelete = (targetId) => { setTodo(todo.filter((it) => it.id !== targetId)); }; 에서 todo.filter((it) => it.id !== targetId) 가 삭제를 하기위해 만들어졌는데 .filter((it) => it.id !== targetId filter 를 쓴 이유와 it.id !== targetId 가 뭔지를 아직도 잘모르겠습니다 to-do list 를 배열을 이용하여 상태 관리를 하는것으로 만들었는데 천천히 공부 해보면서 적용 해볼려고 합니다 공부할떄 선생님께서 보는 학습자료나 to-do list 를 만들때 특별히 참고한게 있었는지 궁금합니다
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
저도 수정 페이지 왔을때 설명과 다르게 아무것도 보이지 않습니다.
밑에 같은 질문을 하신 분이 계시던데요.12.15 챕터의 10:33 초에 보면 수정 으로 들어 왔을때기본값으로 수정 전 데이터가 나온다고 되어 있습니다.지금까지 영상을 보면서 같이 코딩을 해오고 있었는데요.. 그런데 밑에 질문 하신 분 처럼 10:33 초 전 까지의 코딩으로는 수정 시 데이터가 나오지 않습니다.그리고 인프런 측 인지..답변 설명에 useEffect 얘기 하시던데.. useEffect(() => { if (initData) { setInput({ ...initData, createdDate: new Date(Number(initData.createdDate)), }); } }, [initData]); 이 부분은 10:33 초 전 까지는 나오지 않았습니다.인프런 측도 답변을 주실려면 정확히 파악 후 답변을 주세요.. 뭐가 잘못된 건가요?useEffect 부분이 없어도 설명대로 수정 으로 들어가면 데이터가 나오는게 맞는건가요?아니면 제가 뭔가 빠트린 것이 있나요?
-
미해결프로그래밍 시작하기 : 웹 입문 (Inflearn Original)
사진과 본문 내용에 패딩이 40px 들어가 있는데 이유를 모르겠습니다
<html> <head> <meta charset="utf-8"> <title>인스타그램</title> <link rel = "stylesheet" href="styles/card.css"> </head> <body> <section class="container"> <article class ="card"> <header> <div class = "circle-image"> <img src="images/inflearn-project-images/profile.png"/> </div> <div class="card-username"> <span>inflearn</span> </div> <div class="option-more"> <button class="transparent-button"><img src="images/inflearn-project-images/icons/mark.png"/></button> </div> </header> <main> <div class="carousel" data="0"> <!--캐러셀 들어갈 영역--> <div> <ul> <li><img src="images/inflearn-project-images/mountain1.jpg"/></li> <li><img src="images/inflearn-project-images/mountain2.jpg"/></li> <li><img src="images/inflearn-project-images/mountain3.jpg"/></li> <li><img src="images/inflearn-project-images/mountain4.jpg"/></li> </ul> <div class="slide slide-left"> <button class="transparent-button"><img src="images/inflearn-project-images/icons/arrow-left.png"/></button> </div> <div class="slide slide-right"> <button class="transparent-button"><img src="images/inflearn-project-images/icons/arrow-right.png"/></button> </div> </div> <footer> <div class = "active"></div> <div></div> <div></div> <div></div> </footer> </div> <div class="card-container"> <dic class="card-buttons"> <div> <button class="transparent-button"> <img src="images/inflearn-project-images/icons/heart.png"/> </button> </div> <div> <button class="transparent-button"> <img src="images/inflearn-project-images/icons/chat.png"/> </button> </div> <div> <button class="transparent-button"> <img src="images/inflearn-project-images/icons/paper-plane.png"/> </button> </div> <div class="last-card-button"> <button class="transparent-button"> <img src="images/inflearn-project-images/icons/bookmark.png"/> </button> </div> </dic> <div class="card-likes"> 좋아요999,999개 </div> <div class="card-content"> <ul> <li> <div> <span> lnflean.user </span>본문 내용 </div> </li> <li class="comment"> <div> <span>lnflean.user</span>댓글 1 <button class="transparent-button"> <img src="images/inflearn-project-images/icons/heart.png"> </button> </div> </li> <li class="comment"> <div> <span>lnflean.user</span>댓글 2 <button class="transparent-button"> <img src="images/inflearn-project-images/icons/heart.png"> </button> </div> </li> </ul> </div> <div class="card-time">7일전</div> </div> </main> <footer class="card-comment"> <input type="text" placeholder="댓글달기..." name="comment"> <div> <button class ="transparent-button">개시</button> </div> </footer> </article> </section> </body> </html>body { padding : 0; margin : 0; } ul, li{ list-style: none; } button.transparent-button{ background-color: transparent; border: 0; outline: 0; cursor: pointer; } .container{ width: 100%; background-color: #f0f0f0; padding: 20px 0; } article.card{ width: 600px; margin: 20px auto; margin-bottom: 60px; background: #fff; border: 1px solid #c0c0c0; border-radius: 3px; } /*** header 시작 ***/ article.card header{ height: 40px; padding: 10px; } article.card header > div { display: inline-block; vertical-align: middle; } .circle-image { height: 100%; padding: 5px; box-sizing: border-box; } .circle-image > img { height: 100%; border-radius: 50%; } .card-username { padding: 10px 0; font-weight: 900; line-height: 20px; margin-left: 5px; font-size: 13px; } .option-more { float: right; padding: 7px; } /*** header 시작 ***/ /*** content 시작 ***/ .card-container{ padding: 5px 10px; } /* 버튼 */ .card-buttons{ padding: 0 5px; margin-top: 5px; } .card-buttons > div{ display: inline-block; margin-right: 10px; } .card-buttons > div.last-card-button { float: right; margin-right: 0; } /* 좋아요*/ .card-likes{ padding: 5px; font-size: 13px; font-weight: 900; } /* 본문*/ .card-content{ padding: 2px 5px; font-size: 13px; } .card-content li > div{ padding: 1px 0; } .card-content li > div > span{ font-weight: 900; } .card-content li.comment > div > button{ float: right; } .card-content li.comment > div > button > img{ width: 12px; margin-right: 5px; } /*시간*/ .card-time{ padding: 3px; font-size: 11px; color: #a0a0a0; } /*푸터*/ footer.card-comment{ position: relative; height: 55px; border-top: 1px solid #e0e0e0; } footer.card-comment input{ width: 100%; height: 100%; border : 0; outline : 0; padding: 0 15px; color: #606060; } footer.card-comment >div{ position: absolute; right: 10px; top: 50%; transform: translateY(-50%); } footer.card-comment > div > button{ color: #0095f6; opacity: 0.5; padding: 10px 5px; } /*캐러셀*/ article.card main .carousel{ width: 100%; position: relative; } article.card main .carousel > div{ overflow: hidden; } article.card main .carousel ul{ width: 10000px; } article.card main .carousel ul >li { display: inline-block; } article.card main .carousel ul > li img{ width: 600; } .slide{ position: absolute; top: 50%; transform: translateY(-50%); padding: 10px; } .slide img { opacity: 0.75; } .slide-right{ right: 0; } .carousel footer{ position: absolute; height: 20px; text-align: center; width: 100%; bottom: -20px; } .carousel footer div{ width: 6px; height: 6px; background-color : #a8a8a8; display: inline-block; border-radius: 50%; } .carousel footer div { width: 6px; height: 6px; background-color: #a8a8a8; } 원인을 찾을 수 없어서 ul style 사용해서 그냥 40px을 지웠는데 왜 40px이 들어가 있는지를 모르겠습니다
-
미해결자바스크립트 알고리즘 문제풀이 입문(코딩테스트 대비)
섹션1의 17번문제 이 풀이로 풀어도 될까요?
<html> <head> <meta charset="UTF-8" /> <title>출력결과</title> </head> <body> <script> function solution(s) { let answer = []; for (e of s) { if (!answer.includes(e)) { answer.push(e); } } return answer; } let str = ["good", "time", "good", "time", "student"]; console.log(solution(str)); </script> </body> </html>