Frontend

Frontend/React

[React] λ¦¬μ•‘νŠΈμ˜ Key에 λŒ€ν•΄ μ•Œμ•„λ³΄μž

ν•œ νšŒμ‚¬μ˜ 기술 μΈν„°λ·°μ—μ„œ λ¦¬μ•‘νŠΈμ˜ key에 λŒ€ν•œ μ§ˆλ¬Έμ„ λ°›μ•˜λ‹€. ν•΄λ‹Ή μ§ˆλ¬Έμ— λŒ€ν•œ λŒ€λ‹΅μ„ ν•˜λŠ” κ³Όμ •μ—μ„œ κ·Έλ™μ•ˆμ— ν”„λ‘œμ νŠΈλ₯Ό μ§„ν–‰ν•˜λ©΄μ„œ 리슀트의 각 ν•­λͺ©μ— keyλ₯Ό ν• λ‹Ήν•˜λŠ” 것을 λ„ˆλ¬΄ λ‹Ήμ—°μ‹œν•œ 것 κ°™λ‹€λŠ” 생각이 λ“€μ–΄ 이에 λŒ€ν•΄ μ•Œμ•„λ³΄λ €κ³  ν•œλ‹€. λ°°μ—΄μ—μ„œ 데이터 λ Œλ”λ§ const people = [ { id: 0, name: 'Creola Katherine Johnson', profession: 'mathematician', }, { id: 1, name: 'Mario José Molina-Pasquel Henríquez', profession: 'chemist', }, ]; export default function List() { const listItems = people.map((person) =>..

Frontend/React

[React] onKeyDown, onKeyUp 이벀트, ν•œκΈ€ μž…λ ₯ μ‹œ ν•¨μˆ˜ 두 번 μ‹€ν–‰λ˜λŠ” 문제 ν•΄κ²°

πŸ”₯ λ°œμƒν•œ 문제 ν…μŠ€νŠΈλ₯Ό μž…λ ₯ν•˜κ³  μ—”ν„°(Enter) ν‚€λ₯Ό λˆ„λ₯΄λ©΄ λͺ©λ‘μ— μƒˆλ‘­κ²Œ μΆ”κ°€λ˜κ³  input 창은 λΉ„μ›Œμ§€λ„λ‘ κ΅¬ν˜„ν–ˆλŠ”λ° 왠지 λͺ¨λ₯΄κ²Œ ν•¨μˆ˜κ°€ 두 번 μ‹€ν–‰λ˜λ©΄μ„œ κΈ°μ‘΄ ν…μŠ€νŠΈμ˜ λ§ˆμ§€λ§‰ κΈ€μžκ°€ λͺ©λ‘μ— μΆ”κ°€λ˜λŠ” λ¬Έμ œκ°€ λ°œμƒν–ˆλ‹€β—οΈ 원인 뢄석 검색해본 κ²°κ³Ό μ΄λŸ¬ν•œ λ¬Έμ œλŠ” 크둬 λΈŒλΌμš°μ €μ—μ„œ ν•œκΈ€μ„ μ‚¬μš©ν•˜λŠ” κ²½μš°μ—λ§Œ λ¬Έμ œκ°€ λ°œμƒν•œλ‹€. (μ˜μ–΄λ‘œ μž…λ ₯ν•˜λ©΄ ν‚€ μ΄λ²€νŠΈκ°€ μ€‘λ³΅μœΌλ‘œ λ°œμƒν•˜μ§€ ❌) ꡬ체적으둜 μœ„ GIFλ₯Ό 보면 ν•œκΈ€ μž…λ ₯ μ‹œ μž…λ ₯ 쀑인 κΈ€μž μ•„λž˜ 검은 밑쀄이 μƒκΈ°λŠ”λ° ν•΄λ‹Ή 밑쀄이 μžˆλŠ” μƒν™©μ—μ„œ ν‚€ μ΄λ²€νŠΈκ°€ λ°œμƒν•˜λ©΄ ν•¨μˆ˜κ°€ 두 번 μ‹€ν–‰λ˜λŠ” λ¬Έμ œκ°€ λ°œμƒν•œλ‹€. ν•œκΈ€μ˜ 경우 자음과 λͺ¨μŒμ˜ μ‘°ν•©μœΌλ‘œ λ§Œλ“€μ–΄μ§€λŠ” μ‘°ν•© 문자이기 λ•Œλ¬Έμ— κΈ€μžκ°€ μ‘°ν•© 쀑인지 쑰합이 λλ‚œ μƒνƒœμΈμ§€λ₯Ό μ•Œ 수 μ—†μ–΄ μƒκΈ°λŠ” λ¬Έμ œμ΄λ‹€. 🧯 ν•΄κ²° 방법 ..

Frontend/JavaScript

[JavaScript] λ¬΄ν•œ 슀크둀 κ΅¬ν˜„ν•˜κΈ°(Intersection Observer API)

λ¬΄ν•œ 슀크둀(Infinite Scroll)μ΄λž€? μ‚¬μš©μžκ°€ νŽ˜μ΄μ§€ ν•˜λ‹¨μ— λ„λ‹¬ν–ˆμ„ λ•Œ, μ½˜ν…μΈ κ°€ 계속 λ‘œλ“œλ˜λŠ” μ‚¬μš©μž κ²½ν—˜(UX) 방식이닀. ν•œ νŽ˜μ΄μ§€ μ•„λž˜λ‘œ 슀크둀 ν•˜λ©΄ 끝없이 μƒˆλ‘œμš΄ 화면을 λ³΄μ—¬μ£Όκ²Œ 되고 이둜 인해 λ§Žμ€ μ–‘μ˜ μ½˜ν…μΈ λ₯Ό 슀크둀 ν•΄μ„œ λ³Ό 수 μžˆλ‹€. νŽ˜μ΄μ§€λ„€μ΄μ…˜μ΄ μ•„λ‹Œ λ¬΄ν•œ 슀크둀둜 κ΅¬ν˜„ν•˜λ €λŠ” μ΄μœ β“ μƒν’ˆ λͺ©λ‘μ—μ„œ μƒν’ˆμ„ λ³΄μ—¬μ£Όκ³ μž ν•  λ•Œ νŽ˜μ΄μ§€λ„€μ΄μ…˜, λ¬΄ν•œ 슀크둀 쀑 무엇이 μ‚¬μš©μž κ²½ν—˜μ„ λ”μš± μ’‹κ²Œ ν•  수 μžˆμ„μ§€ κ³ λ―Όν•œ 끝에 λͺ¨λ°”일 ν™˜κ²½μ„ κ³ λ €ν•΄μ„œ λ¬΄ν•œ μŠ€ν¬λ‘€μ„ μ‚¬μš©ν•˜κΈ°λ‘œ ν–ˆλ‹€.(차후에 ν”„λ‘œμ νŠΈλ₯Ό λ°˜μ‘ν˜•μœΌλ‘œ λ¦¬νŒ©ν„°λ§ ν•  κ³„νšπŸ™‡πŸ») λ˜ν•œ, λ‹€μŒ μƒν’ˆμ„ 보기 μœ„ν•œ μ‚¬μš©μžμ˜ 클릭을 μ΅œμ†Œν™”ν•˜κ³  더 μ‰½κ²Œ λ‹€μ–‘ν•œ μƒν’ˆμ„ λ³Ό 수 μžˆμ„ 것이라고 νŒλ‹¨ν–ˆλ‹€. κ΅¬ν˜„ν•˜λŠ” κ³Όμ • λ¬΄ν•œ μŠ€ν¬λ‘€μ„ κ΅¬ν˜„ν•˜λŠ” 방법은 슀크..

Frontend/React

[React] [Immer] "An immer producer returned a new value and modified its draft. Either return a new value or modify the draft." μ—λŸ¬ ν•΄κ²°

πŸ”₯ λ°œμƒν•œ μ—λŸ¬ Uncaught Error: [Immer] An immer producer returned a new value and modified its draft. Either return a new value or modify the draft. μ—λŸ¬λ₯Ό λ²ˆμ—­ν•˜μžλ©΄ immer μ œμž‘μžλŠ” μƒˆλ‘œμš΄ 값을 λ¦¬ν„΄ν•˜κ±°λ‚˜ κΈ°μ‘΄ μƒνƒœλ₯Ό μˆ˜μ •ν•˜κ±°λ‚˜ λ‘˜ 쀑 ν•˜λ‚˜λ§Œ ν•΄μ•Όλœλ‹€λŠ” 것이닀. 원인이 λ˜λŠ” μ½”λ“œ 뢄석 immer 라이브러리λ₯Ό μ‚¬μš©ν•˜μ—¬ λΆˆλ³€μ„± μƒνƒœμ˜ 트리λ₯Ό μ†μ‰½κ²Œ λ³€κ²½ν•˜λ˜ 쀑 μœ„μ™€ 같은 μ—λŸ¬κ°€ λ°œμƒν–ˆλ‹€. updatePerson((person) => person.mentors.push({ name, title })); ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” μ€‘κ΄„ν˜Έλ₯Ό 써주지 μ•ŠμœΌλ©΄ μžλ™μœΌλ‘œ return ν‚€μ›Œλ“œκ°€ λΆ™λŠ”λ‹€. 즉, μœ„μ˜ μ½”λ“œλŠ” κΈ°μ‘΄..

Frontend/JavaScript

[Axios] Axios 인터셉터 μ μš©ν•˜κΈ°

인터셉터(Interceptors)λž€? then λ˜λŠ” catch둜 처리되기 전에 μš”μ²­κ³Ό 응닡을 κ°€λ‘œμ±Œ 수 μžˆλ‹€. Axios 인터셉터λ₯Ό μ μš©ν•˜λ €λŠ” μ΄μœ β“ 토이 ν”„λ‘œμ νŠΈλ₯Ό μ§„ν–‰ν•˜λ©΄μ„œ μ„œλ²„μ— 토큰 인증을 ν•„μš”λ‘œ ν•˜λŠ” API μš”μ²­μ„ ν• λ•Œλ§ˆλ‹€ HTTP Authorization μš”μ²­ 헀더에 토큰을 λ„£μ–΄μ€˜μ•Όν•˜κ³  401(Unauthorized) μ—λŸ¬κ°€ μ„œλ²„λ‘œλΆ€ν„° λ“€μ–΄μ˜€λ©΄ 토큰을 κ°±μ‹ ν•΄μ€€ ν›„ μž¬μš”μ²­μ„ λ³΄λ‚΄λŠ” 과정을 ν•œ κ³³μ—μ„œ λͺ¨λ‘ μ²˜λ¦¬ν•˜μ—¬ 쀑볡 μ½”λ“œλ₯Ό μ œκ±°ν•˜κ³  μœ μ§€λ³΄μˆ˜μ„±μ„ ν–₯μƒμ‹œν‚€κΈ° μœ„ν•΄ Axios 인터셉터λ₯Ό μ μš©ν•˜κΈ°λ‘œ ν–ˆλ‹€. μ‚¬μš©μž 지정 config둜 μƒˆλ‘œμš΄ Axios μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ—¬ μ‚¬μš©ν•˜λ‹ˆ λ”μš± νŽΈλ¦¬ν–ˆλ‹€. (baseURL, timeout μ„€μ •) μ μš©ν•˜λŠ” κ³Όμ • 1) Axios μΈμŠ€ν„΄μŠ€ 생성 const instanc..

Frontend/JavaScript

[JavaScript] μ •κ·œ ν‘œν˜„μ‹ μ•ˆμ— λ™μ μœΌλ‘œ λ³€μˆ˜λ₯Ό λ„£λŠ” 방법

μ •κ·œ ν‘œν˜„μ‹(Regular Expression)은 λ¬Έμžμ—΄μ—μ„œ νŠΉμ • 문자 쑰합을 μ°ΎκΈ° μœ„ν•œ νŒ¨ν„΄μ΄λ‹€. RegExp RegExp μƒμ„±μžλŠ” νŒ¨ν„΄μ„ μ‚¬μš©ν•΄ ν…μŠ€νŠΈλ₯Ό νŒλ³„ν•  λ•Œ μ‚¬μš©ν•œλ‹€. λ¦¬ν„°λŸ΄ ν‘œκΈ°λ²•μ˜ λ§€κ°œλ³€μˆ˜λŠ” 두 λΉ—κΈˆμœΌλ‘œ 감싸야 ν•˜λ©° λ”°μ˜΄ν‘œλ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€. μƒμ„±μž ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λŠ” λΉ—κΈˆμœΌλ‘œ 감싸지 μ•ŠμœΌλ‚˜ λ”°μ˜΄ν‘œλ₯Ό μ‚¬μš©ν•œλ‹€. // μ •κ·œ ν‘œν˜„μ‹ μƒμ„±ν•˜κΈ° /ab/g new RegExp(/ab/, 'g') // λ¦¬ν„°λŸ΄ new RegExp('ab', 'g') // μƒμ„±μž λ™μ μœΌλ‘œ μ •κ·œ ν‘œν˜„μ‹ μƒμ„±ν•˜κΈ° const λ³€μˆ˜ = 'JS'; const regex = new RegExp(`${λ³€μˆ˜}`, 'g'); console.log(regex); // /JS/g 🧐 μ‘μš©ν•˜κΈ° match() λ©”μ„œλ“œλŠ” λ¬Έμžμ—΄μ΄ μ •κ·œμ‹κ³Ό λ§€μΉ˜λ˜λŠ”..

Frontend/JavaScript

[JavaScript] μ—°κ²° 리슀트둜 큐(Queue) κ΅¬ν˜„ν•˜λŠ” 방법

큐(Queue)λž€? νλŠ” 데이터λ₯Ό μΌμ‹œμ μœΌλ‘œ μ €μž₯ν•˜λŠ” 자료ꡬ쑰 쀑 ν•˜λ‚˜λ‘œ, λ¨Όμ € μž…λ ₯된 데이터가 λ¨Όμ € 좜λ ₯λ˜λŠ” "μ„ μž…μ„ μΆœ(FIFO: First-In-First-Out)" 원칙을 λ”°λ¦…λ‹ˆλ‹€. 큐(Queue)의 κ΅¬ν˜„ 방법 2가지 νλŠ” λ°°μ—΄(Array)μ΄λ‚˜ μ—°κ²° 리슀트(Linked List)λ₯Ό μ‚¬μš©ν•˜μ—¬ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 1️⃣ λ°°μ—΄ 배열을 μ‚¬μš©ν•  경우, 크기가 κ³ μ •λ˜μ–΄ μžˆμ–΄μ„œ λ°μ΄ν„°μ˜ μΆ”κ°€ 및 μ œκ±°μ— μ œν•œμ΄ μžˆμ„ 수 μžˆμ§€λ§Œ, μ—°μ‚° 속도가 λΉ λ¦…λ‹ˆλ‹€. 2️⃣ μ—°κ²° 리슀트 μ—°κ²° 리슀트λ₯Ό μ‚¬μš©ν•  경우, 크기에 μ œν•œμ΄ μ—†μ–΄μ„œ 데이터λ₯Ό μœ λ™μ μœΌλ‘œ μΆ”κ°€ 및 μ œκ±°ν•  수 μžˆμ§€λ§Œ, μ—°μ‚° 속도가 λŠλ¦½λ‹ˆλ‹€. 🧐 λ°°μ—΄λ‘œ 큐(Queue)λ₯Ό κ΅¬ν˜„ν•΄λ„ λ˜μ§€λ§Œ ꡳ이 ? μ—°κ²° 리슀트둜 κ΅¬ν˜„ν•΄μ•Ό ν•˜λŠ” 이유 JavaScriptμ—μ„œ 배열을 μ‚¬μš©..

Frontend/React

[React/Axios] 🀬 Axios message: 'Network Error'(CORS 였λ₯˜)

🚨 였λ₯˜ λ°œμƒ AxiosError message: 'Network Error' const userInfoPatch = async (userInfo) => { try { // url: μ„œλ²„ μ£Όμ†Œ, id: μ‚¬μš©μž 아이디, userInfo: μ‚¬μš©μž 정보 객체 await axios.patch(`${url}/member/${id}`, userInfo).then(() => { alert('μˆ˜μ •μ΄ μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.'); }); } catch (error) { console.log(error); } }; ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œμ—μ„œλŠ” 별닀λ₯Έ λ¬Έμ œκ°€ μ—†μ–΄ λ³΄μ˜€κ³ , μ„œλ²„ μΈ‘μ—μ„œ λΆ„λͺ… 접근을 ν—ˆμš©ν•˜λŠ” λ©”μ„œλ“œλ‘œ PATCH에 λŒ€ν•΄ λ”°λ‘œ 처리λ₯Ό ν•΄μ£Όμ—ˆλ‹€. ν”„λ‘œμ νŠΈλ₯Ό μ§„ν–‰ν•˜λ©΄μ„œ GET, POST, DELETE λ“± μ—¬λŸ¬ λ°©μ‹μœΌλ‘œ μ„œλ²„μ— μš”μ²­ν• ..

ν”„λ‘ νŠΈμ—”λ“œ μ—”μ§€λ‹ˆμ–΄
'Frontend' μΉ΄ν…Œκ³ λ¦¬μ˜ κΈ€ λͺ©λ‘