묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
input 태그 value문제 해결 방법
초기값이 '' 이여서강의에서는 value 값을 맨뒤로 넣고 input 태그에 닫힘을 작성하지 않음으로, 동작하게 하였는데 다른 방법으로는 <input type="text" placeholder="Search" id="search" value="${searchWord}" autocomplete="off"/>로 작성하였습니다, value 를 싱글쿼터나 더블쿼터로 감싼다음 ${} 를 사용하시면, 뒤에다가 다른 속성을 넣거나 닫아도 정상 동작합니다. 참고 하실분 참고하셔도 좋습니다.
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
9분 30초 || 'all' 영상 누락
혹시나 기본 '/' 경로에서 펭귄눌렀다 popstate 로 뒤로갔을 경우'clicked' css가 먹지않는 현상, 강의 내용에서 저부분이 영상 짤려서 놓치기 쉬울꺼 같습니다. 저도 강의보면서 하다가 || 'all' 하는 부분 제대로 보기힘들어서못 적었다가 나중에 문제생겨서 로직 보다가 발견했습니다,
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
영상보고 직접 api를 구현해봤는데 자꾸 프로젝트를 변경하면 서버가 꺼지;는데 방법이 있을까요
코드 관련 질문은 아래와 같이 '코드블럭' 기능을 이용해주세요!+ 오류 메세지도 함께 올려주시면 좋아요 🙂console.log('hello'); 이런식으로 구축했는데 프로젝트만 바꾸면 서버가 꺼져서요..
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
경로 질문드립니다
코드 관련 질문은 아래와 같이 '코드블럭' 기능을 이용해주세요!+ 오류 메세지도 함께 올려주시면 좋아요 🙂npm error code ENOENT npm error syscall open npm error path C:\Users\사용자이름\Desktop\animal_album_Main\animal_album-3\package.json npm error errno -4058 npm error enoent ENOENT: no such file or directory, open 'C:\Users\사용자이름\Desktop\animal_album_Main\animal_album-3\package.json' npm error enoent This is related to npm not being able to find a file. npm error enoent npm error A complete log of this run can be found in: C:\Users\사용자이름\AppData\Local\npm-cache\_logs\2024-12-06T08_26_22_967Z-debug-0.log 안녕하세요 질문드립니다몇일동안 npm init 떄문에 질문드립니다 npm 설치시 해당 프로젝트 파일이 c드라이브 안에만 있어야 되는건가요 ?1번 바탕화면에 프로젝트가 있을떄도 실행이 안됩니다2번 c드라이브 -> User -> (사용자이름) -> github-> 해당 폴더 -> 프로젝트 폴더3번 c드라이브 -> 프로젝트 폴더 3번일때만 되고 1,2번일때는 npm init 설치가 안되는데2번도 가능하게 할려면 어떻게 해야하는지 궁금합니다
-
해결됨[React / VanillaJS] UI 요소 직접 만들기 Part 2
popover createPortal 방식에서
portal할 요소를 아래처럼 작성하고 있는데<div id="popoverRoot" /> 저는 이거를 popover를 사용하는 개발자가 신경안쓸 수 있도록 하는 방법이 있지않을까 해서 두 가지 방법을 생각했는데하나는 useLayoutEffect 내부에서 아래와 같은 로직으로 div요소를 만드는 방법하고, useLayoutEffect(() => { if (typeof window !== 'undefined') { const portalElement = document.getElementById(portalId) if (!portalElement) { const newPortalElement = document.createElement('div') newPortalElement.id = portalId document.body.appendChild(newPortalElement) } } }, [])아니면 document.body로 보내는 방법을 생각했는데 return createPortal( ... , document.body )두 방법 중 어느게 적절한지를 잘 모르겠어서..혹은 위 방법처럼 했을 때 어떤 문제가 생기는지도 아직 예상이 안되는데 혹시 강사님의 생각은 어떠신지 궁금합니다!
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
regionList 에 region별 cities가 정상 로딩이 안됩니다.
영상 7:53 부분에 코드를 완성하면, regionList에 있는 region 클릭 시, 영상처럼 region 별로 cities가 나와야 하지만, 아래 에러가 생겨서 정상적으로 로딩이 안됩니다.혹시 어떤 문제 인지 알려주시면, 너무 고맙습니다. 감사합니다! app.js 코드는 아래와 같이 입력했습니다.import Header from "./components/Header.js"; import RegionList from "./components/RegionList.js"; import CityList from "./components/CityList.js"; import CityDetail from "./components/CityDetail.js"; import { request } from "./components/api.js"; export default function App($app) { const getSortBy = () => { if (window.location.search) { return window.location.search.split("sort=")[1].split("&")[0]; } return "total"; }; const getSearchWord = () => { if (window.location.search && window.location.search.includes("search=")) { return window.location.search.split("search=")[1]; } return ""; }; this.state = { startIdx: 0, sortBy: getSortBy(), searchWord: getSearchWord(), region: "", cities: "", }; const header = new Header({ $app, initialState: { sortBy: this.state.sortBy, searchWord: this.state.searchWord, }, handleSortChange: async (sortBy) => { const pageUrl = `/${this.state.region}?sort=${sortBy}`; history.pushState( null, null, this.state.searchWord ? pageUrl + `&search=${this.state.searchWord}` : pageUrl ); const cities = await request( 0, this.state.region, sortBy, this.state.searchWord ); this.setState({ ...this.state, startIdx: 0, sortBy: sortBy, cities: cities, }); }, handleSearch: async (searchWord) => { history.pushState( null, null, `/${this.state.region}?sort=${this.state.sortBy}&search=${searchWord}` ); const cities = await request( 0, this.state.region, this.state.sortBy, searchWord ); this.setState({ ...this.state, startIdx: 0, searchWord: searchWord, cities: cities, }); }, }); const regionList = new RegionList({ $app, initialState: this.state.region, handleRegion: async (region) => { history.pushState(null, null, `/${region}?sort=total`); const cities = await request(0, region, "total"); this.setState({ ...this.state, startIdx: 0, sortBy: "total", region: region, searchWord: "", cities: cities, }); }, }); const cityList = new CityList({ $app, initialState: this.state.cities, handleLoadMore: async () => { const newStartIdx = this.state.startIdx + 40; const newCities = await request( newStartIdx, this.state.region, this.state.sortBy, this.state.searchWord ); this.setState({ ...this.state, startIdx: newStartIdx, cities: { cities: [...this.state.cities.cities, ...newCities.cities], isEnd: newCities.isEnd, }, }); }, }); const cityDetail = new CityDetail(); this.setState = (newState) => { this.state = newState; cityList.setState(this.state.cities); header.setState({ sortBy: this.state.sortBy, searchWord: this.state.searchWord, }); regionList.setState(this.state.region); }; const init = async () => { const cities = await request( this.state.startIdx, this.state.region, this.state.sortBy, this.state.searchWord ); console.log(cities); this.setState({ ...this.state, cities: cities, }); }; init(); } regionList.js 코드는 아래와 같이 입력했습니다.export default function RegionList({ $app, initialState, handleRegion }) { this.state = initialState; this.$target = document.createElement("div"); this.$target.className = "region-list"; this.handleRegion = handleRegion; $app.appendChild(this.$target); this.template = () => { const regionList = [ "🚀 All", "🌏 Asia", "🕌 Middle-East", "🇪🇺 Europe", "💃 Latin-America", "🐘 Africa", "🏈 North-America", "🏄 Oceania", ]; let temp = ``; regionList.forEach((elm) => { let regionId = elm.split(" ")[1]; temp += `<div id=${regionId}>${elm}</div>`; }); return temp; }; this.render = () => { this.$target.innerHTML = this.template(); if (this.state) { let $currentRegion = document.getElementById(this.state); $currentRegion && ($currentRegion.className = "clicked"); } else { document.getElementById("All").className = "clicked"; } const $regionList = this.$target.querySelectorAll("div"); $regionList.forEach((elm) => { elm.addEventListener("click", () => { this.handleRegion(elm.id); }); }); }; this.setState = (newState) => { this.state = newState; this.render(); }; this.render(); }
-
해결됨[React / VanillaJS] UI 요소 직접 만들기 Part 1
[#보일러플레이트 코드 사용법 문의] 강의자료[보일러플레이트] 사용법에 대해서 문의 드려요
안녕하세요!보일러플레이트 코드를 다운받아 npm install 을 하면,route 관련 코드가 작성되어 있고,http://localhost:3000으로 브라우저를 들어가면좌측 메뉴가 disabled 되어 클릭이 안되는 상태입니다. route 설정 코드가 보일러플레이트 코드에 일부 작성되어 있는데, route 설정 강좌를 시청 해야하는지 혹은 강좌 내용대로 코드를 다시 작성해야하는지 궁금합니다. routes.ts를 보면,children의 값이 null 인 부분이 확인됩니다. 아코디언 강좌를 예로 든다면,아코디언 컴포넌트를 만들고, 여기 null 인 부분에 값을 넣는거 아닐까 생각이 드는데요 첨부된 보일러플레이트 코드를 어떻게 사용해야하는지 질문 드립니다. 감사합니다! :]
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
regionList 클릭시 해당 cities가 안나옵니다.
혼자서 찾아보려고 했는데 도저히 모르겠네요 ㅜ 오류메세지는 나오는건 없고 제목과 같습니다. region을 선택하면 해당 cities가 나와야하는데 안나와요 ㅜ import Header from "./components/Header.js"; import RegionList from "./components/RegionList.js"; import CityDetail from "./components/CityDetail.js"; import CityList from "./components/CityList.js"; import { request } from "./components/api.js"; export default function App($app){ const getSortBy = () => { if (window.location.search){ return window.location.search.split('sort=')[1].split('&')[0]; } return 'total'; }; const getsearchWord = () => { if(window.location.search && window.location.search.includes('search=')){ return window.location.search.split('search=')[1] } //뒤에 있는 값을 반환 return ''; }; this.state={ startIdx : 0, sortBy : getSortBy(), region: '', searchWord: getsearchWord(), cities:'', }; const header = new Header({ $app, initialState:{ sortBy:this.state.sortBy, searchWord:this.state.searchWord }, handleSortChange: async(sortBy) => { const pageUrl = `/${this.state.region}?sort=${sortBy}`; history.pushState( null, null, this.state.searchWord ? pageUrl + `&search=${this.state.searchWord}` : pageUrl ); //변경된 정렬기준을 적용한 새로운 데이터를 불러옴 (매개변수로 전달받은 새로운 정렬기준인 sortBy 값을 넣어야함) const cities = await request(0, this.state.region, sortBy, this.state.searchWord); // 변경된 상태값을 업데이트 this.setState({ ...this.state, startIdx:0, sortBy: sortBy, cities: cities, }); }, handleSearch: async(searchWord) => { //웹사이트 주소를 알맞게 변경 history.pushState( null, null, `/${this.state.region}?sort=${this.state.sortBy}&search=${searchWord}` ); const cities = await request(0, this.state.region, this.state.sortBy, searchWord); this.setState({ ...this.state, startIdx:0, searchWord: searchWord, cities: cities }) }, }); const regionList = new RegionList({ $app, initialState:this.state.region, handleRegion: async(region) => { history.pushState(null, null, `/${region}?sort=total`); const cities = await request(0, region, 'total'); console.log("cities",cities) this.setState({ ...this.state, startIdx: 0, region: region, sortBy: 'total', cities: cities, searchWord: '', }); }, }); const cityList = new CityList({ $app, initialState:this.state.cities, // 아래는 더보기 버튼을 눌렀을 때 실행되는 것 handleLoadMore: async() => { const newStartIdx = this.state.startIdx + 40; const newCities = await request(newStartIdx, this.state.region, this.state.sortBy, this.state.searchWord); this.setState({ ...this.state, startIdx : newStartIdx, cities:{ cities:[...this.state.cities.cities, ...newCities.cities], isEnd: newCities.isEnd, } }) } }); const cityDetail = new CityDetail(); this.setState = (newState) => { this.state = newState; cityList.setState(this.state.cities); header.setState({sortBy:this.state.sortBy, searchWord:this.state.searchWord}); regionList.setState(this.state.region); }; const init = async() => { const cities = await request(this.state.startIdx, this.state.sortBy, this.state.region, this.state.searchWord); this.setState({ ...this.state, cities: cities, //api 호출의 결과인 cities }); }; init(); } export default function RegionList({$app, initialState, handleRegion}){ this.state = initialState; this.$target = document.createElement('div'); this.$target.className = 'region-list'; this.handleRegion = handleRegion; $app.appendChild(this.$target); this.template = () => { const regionList = [ '🚀 All', '🌏 Asia', '🕌 Middle-East', '🇪🇺 Europe', '💃 Latin-America', '🐘 Africa', '🏈 North-America', '🏄 Oceania', ]; let temp = ``; regionList.forEach((elm) => { let regionId = elm.split(' ')[1]; temp += `<div id=${regionId}>${elm}</div>`; }); return temp; }; this.render = () => { this.$target.innerHTML = this.template(); let $currentRegion; if(this.state){ $currentRegion = document.getElementById(this.state); $currentRegion && ($currentRegion.className = 'clicked'); } else { document.getElementById('All').className = 'clicked'; } const $regionList = this.$target.querySelectorAll('div'); $regionList.forEach((elm) => { elm.addEventListener('click', () => { this.handleRegion(elm.id); }); }); }; this.setState = (newState) => { this.state = newState; this.render(); }; this.render(); }
-
해결됨[React / VanillaJS] UI 요소 직접 만들기 Part 2
스낵바를 만들 때 snackBarContext와 snackBarSetContext
스낵바를 만들 때 snackBarContext와 snackBarSetContext를 둘로 나누셔서 관리하는데 이렇게 하신 이유나 장점을 정확히 알 수 있을까요?단점도 알려주시면 감사드리겠습니다.
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
select값이 출력이 안돼요
input 값은 나오는데 select 값은 출력이 안돼요 ㅠ 오류 메세지도 따로 나오는 건 없고 console.log로 cities 값을 볼려고 했는데 빈 Array가 나옵니다 ㅠ import Header from "./components/Header.js"; import RegionList from "./components/RegionList.js"; import CityDetail from "./components/CityDetail.js"; import CityList from "./components/CityList.js"; import { request } from "./components/api.js"; export default function App($app){ const getSortBy = () => { if (window.location.search){ return window.location.search.split('sort=')[1].split('&')[0]; } return 'total'; }; const getSearchWorld = () => { if(window.location.search && window.location.search.includes('search=')){ return window.location.search.split('search=')[1] } //뒤에 있는 값을 반환 return ''; }; this.state={ startIdx : 0, sortBy : getSortBy(), searchWorld: getSearchWorld(), region: '', cities:'', }; const header = new Header({ $app, initialState:{ sortBy:this.state.sortBy, searchWorld:this.state.searchWorld }, handleSortChange: async(sortBy) => { const pageUrl = `/${this.state.region}?sort=${sortBy}`; history.pushState( null, null, this.state.searchWorld ? pageUrl + `&search=${this.state.searchWorld}` : pageUrl ); //변경된 정렬기준을 적용한 새로운 데이터를 불러옴 (매개변수로 전달받은 새로운 정렬기준인 sortBy 값을 넣어야함) const cities = await request(0, this.state.region, sortBy, this.state.searchWorld); console.log(cities) // 변경된 상태값을 업데이트 this.setState({ ...this.state, startIdx:0, sortBy: sortBy, cities: cities, }); }, handleSearch: async(searchWorld) => { //웹사이트 주소를 알맞게 변경 history.pushState( null, null, `/${this.state.region}?sort=${this.state.sortBy}&search=${searchWorld}` ); const cities = await request(0, this.state.region, this.state.sortBy, searchWorld); this.setState({ ...this.state, startIdx:0, searchWorld: searchWorld, cities: cities }) }, }); const regionList = new RegionList(); const cityList = new CityList({ $app, initialState:this.state.cities, // 아래는 더보기 버튼을 눌렀을 때 실행되는 것 handleLoadMore: async() => { const newStartIdx = this.state.startIdx + 40; const newCities = await request(newStartIdx, this.state.sortBy, this.state.region, this.state.searchWorld); this.setState({ ...this.state, startIdx : newStartIdx, cities:{ cities:[...this.state.cities.cities, ...newCities.cities], isEnd: newCities.isEnd, } }) } }); const cityDetail = new CityDetail(); this.setState = (newState) => { this.state = newState; cityList.setState(this.state.cities); header.setState({sortBy:this.state.sortBy, searchWorld:this.state.searchWorld}); }; const init = async() => { const cities = await request(this.state.startIdx, this.state.sortBy, this.state.region, this.state.searchWorld); this.setState({ ...this.state, cities: cities, //api 호출의 결과인 cities }); }; init(); }
-
해결됨웹 프론트엔드를 위한 자바스크립트 첫걸음
왜 전부다 div태그로 만드는지 궁금합니다.
강사님 강의를 들으면서 의문이 들었는데 강사님 버튼 부분으로 되어있는 것들을 div태그로 전부다 만드시던데 혹시 이유가 따로 있을까요???북마크를 추가하는 부분이나 취소, 추가 부분은 button태그를 사용하거나 북마크를 입력하는 div태그 전체를 form태그로 묶어서 사용하는게 좀 더 좋지 않을까요??강사님이 div 태그만 사용하시던데 혹시 이유가 따로 있으신건가요??
-
해결됨웹 프론트엔드를 위한 자바스크립트 첫걸음
[수업질문] bookmark.js에서
6, 북마크 아이템 추가하기에서 추가 버튼을 누르면 bookmarkList.push is not a function at HTMLDivElement.addBookMarkItem 이라고 콘솔에 나옵니다 ..ㅠㅠ(css와 마크업은 미리 적어두었습니다.)
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
컴포넌트에 매개변수 전달하는 방식에 대하여
프로젝트 작성할 때 ,APP.js와 components폴더 안의 js모듈로 보통 구성을 하시는데,왜 APP.js에서 $app을 매개변수로 받을 때는 소괄호에서 바로 받는데,다른 컨포넌트 내부 js모듈에서는 중괄호로 받는건가요? export default function App($app) {} export default function CityList({ $app, initialState,handleLoadMore }) {} APP의 경우 전달받는게 하나인데, CityList의 경우 APP에서 여러개의 매개변수를 받아오기 떄문에 구조분해로 받아오는 건가요? 만약 그렇다면 한개만 매개변수로 받아오는 경우, CityList도 (소괄호)안에 {중괄호}없이 바로 매개변수를 써도 되는 건가요?
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
require 질문드립니다.
안녕하세요! 동물앨범 수업 따라가던 중 질문이 생겨 문의드립니다.require함수 작성시 밑줄이 생기며 require is not defined라는 에러가 뜨는데, 저대로 실행을 하면 정상 작동하긴 합니다. 구글링을 해보니 package.json파일에 "type":commonJs를 추가하라고 하여 했는데도 똑같이 밑줄이 생깁니다. 어떤게 문제일까요?
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
동물앨범 3-3 express 설치 후
express 파일까지 설치하고 server.js에 코드를 작성해 주었습니다.그런데 웹을 새로고침한 경우Cannot GET /penguin이런 에러가 계속 발생합니다. 이 에러를 해결하기 위해서 express를 설치한 것 같은데..무엇이 문제인 걸까요?혹시 몰라 깃의 코드를 확인해 봤는데, 코드상 문제는 없었습니다. import Content from "./components/Content.js"; import TabBar from "./components/TabBar.js"; import { request } from "./components/api.js"; export default function App($app) { this.state = { currentTab: window.location.pathname.replace("/", "") || "all", photos: [], }; //tab const tab = new TabBar({ $app, initialState: this.state.currentTab, onClick: async (name) => { history.pushState(null, null, `/${name}`); this.updateContent(name); }, }); const content = new Content({ $app, initialState: [], }); // 상태 업데이트 함수 this.setState = (newState) => { this.state = newState; tab.setState(this.state.currentTab); content.setState(this.state.photos); }; this.updateContent = async (tabName) => { try { const currentTab = tabName === "all" ? '' : tabName; const photos = await request(currentTab); this.setState({ ...this.state, currentTab: tabName, photos:photos, }) } catch (error) { console.log(error) } }; window.addEventListener("popstate", () => { this.updateContent(window.location.pathname.replace("/", "") || "all"); }); const init = async () => { this.updateContent(this.state.currentTab); }; init(); } const express = require('express'); const path = require("path"); const app = express(); const PORT = 3000; app.use(express.static(path.join(__dirname, ".."))); app.get("/*", (req, res) => { res.sendFile(path.join(__dirname, "..", 'index.html')); }); app.listen(PORT, () => { console.log('START SERVER') })++추가질문port주소를 3000으로 변경하면 해당 오류가 발생하지 않는 것을 확인했습니다. 라이브서버를 자동으로 실행하면 port가 5500이어서 오류가 발생한 것 같습니다.1) port는 자동으로 3000으로 변경이 안되나요?2)server.js에서 port를 새로 지정해준 이유가 궁금합니다. 그대로 5500을 하면 안되나요?
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
동물앨범만들기3 질문드립니다.
안녕하세요! 강의 너무 잘 수강하고 있습니다.App.js 컴포넌트에서 onClick함수를 저렇게 정의하면 올바르게 동작하는 건 알겠는데이런식으로 코드를 작성해 tabbar 컴포넌트에서 onClick함수를 실행하면 오류가 뜨는 이유가 궁금합니다!
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
동물앨범만들기 2-2
export default function TabBar({$app, initialState, onClick }) { this.state = initialState; this.onClick = onClick; this.$target = document.createElement('div'); this.$target.className = 'tab-bar'; $app.appendChild(this.$target); // 필요한 버튼 this.template = () => { let temp = `<div id="all">전체</div> <div id ="penguin">펭귄</div> <div id ="koala">코알라</div> <div id="panda">판다</div>`; return temp; }; this.render = () => { this.$target.innerHTML = this.template(); //$currentTab변수에 현재 state값과 동일한 아이디를 갖는 버튼 요소 할당 let $currentTab = document.getElementById(this.state); //$currentTab ? ($currentTab.className = "clicked") : ""; $currentTab && ($currentTab.className = "clicked");동물 앨범 만들기 2-2 강의부분에서$currentTab 변수에 현재 state값과 동일한 아이디를 갖는 버튼 요소를 할당한다고 하셔쓴데,왜 this.state가 들어가는지 이해가 가지 않습니다.this.state값은 initialState이고 initialState은 APP컴포넌트에서 빈문자열이었는데...그 뒤로 추론이 되지 않아서....흐름? 좀 알려주세요ㅡㅠ
-
해결됨[React / VanillaJS] UI 요소 직접 만들기 Part 1
무한스크롤 리액트버전 | 16분 31초
16분 31초에 const useInfiniteFetcher =() => {} 여기 부분을 보게 되면pageData는 async에서 받아와서 promise가 되었는데강사님은 따로 .then을 안하셨는데 어떻게 가능한가요??
-
해결됨한 번에 끝내는 자바스크립트: 바닐라 자바스크립트로 SPA 개발까지
package.json
package.json을 설치할때 해당파일의 설치 위치가 꼭 server파일의 상위폴더인 TRIP-WIKI폴더여야하나요?server파일안에 설치해도 상관없는건지 상관있으면 무엇이 다른건지 알수 있을까요?
-
해결됨웹 프론트엔드를 위한 자바스크립트 첫걸음
최종 프로젝트 적용
영상 촬영 시기와 현재 크롬 화면이 달라서 질문드립니다. 개발자 모드가 없어서 그런데 등록을 마쳐야 적용 가능할까요?