[React] ๋ฆฌ์•กํŠธ์˜ Key์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž
ยท
Frontend/React
ํ•œ ํšŒ์‚ฌ์˜ ๊ธฐ์ˆ  ์ธํ„ฐ๋ทฐ์—์„œ ๋ฆฌ์•กํŠธ์˜ 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) =>..
[React] onKeyDown, onKeyUp ์ด๋ฒคํŠธ, ํ•œ๊ธ€ ์ž…๋ ฅ ์‹œ ํ•จ์ˆ˜ ๋‘ ๋ฒˆ ์‹คํ–‰๋˜๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ
ยท
Frontend/React
๐Ÿ”ฅ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ์—”ํ„ฐ(Enter) ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋ชฉ๋ก์— ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€๋˜๊ณ  input ์ฐฝ์€ ๋น„์›Œ์ง€๋„๋ก ๊ตฌํ˜„ํ–ˆ๋Š”๋ฐ ์™ ์ง€ ๋ชจ๋ฅด๊ฒŒ ํ•จ์ˆ˜๊ฐ€ ๋‘ ๋ฒˆ ์‹คํ–‰๋˜๋ฉด์„œ ๊ธฐ์กด ํ…์ŠคํŠธ์˜ ๋งˆ์ง€๋ง‰ ๊ธ€์ž๊ฐ€ ๋ชฉ๋ก์— ์ถ”๊ฐ€๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹คโ—๏ธ ์›์ธ ๋ถ„์„ ๊ฒ€์ƒ‰ํ•ด๋ณธ ๊ฒฐ๊ณผ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋Š” ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ•œ๊ธ€์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. (์˜์–ด๋กœ ์ž…๋ ฅํ•˜๋ฉด ํ‚ค ์ด๋ฒคํŠธ๊ฐ€ ์ค‘๋ณต์œผ๋กœ ๋ฐœ์ƒํ•˜์ง€ โŒ) ๊ตฌ์ฒด์ ์œผ๋กœ ์œ„ GIF๋ฅผ ๋ณด๋ฉด ํ•œ๊ธ€ ์ž…๋ ฅ ์‹œ ์ž…๋ ฅ ์ค‘์ธ ๊ธ€์ž ์•„๋ž˜ ๊ฒ€์€ ๋ฐ‘์ค„์ด ์ƒ๊ธฐ๋Š”๋ฐ ํ•ด๋‹น ๋ฐ‘์ค„์ด ์žˆ๋Š” ์ƒํ™ฉ์—์„œ ํ‚ค ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํ•จ์ˆ˜๊ฐ€ ๋‘ ๋ฒˆ ์‹คํ–‰๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ํ•œ๊ธ€์˜ ๊ฒฝ์šฐ ์ž์Œ๊ณผ ๋ชจ์Œ์˜ ์กฐํ•ฉ์œผ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ์กฐํ•ฉ ๋ฌธ์ž์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ธ€์ž๊ฐ€ ์กฐํ•ฉ ์ค‘์ธ์ง€ ์กฐํ•ฉ์ด ๋๋‚œ ์ƒํƒœ์ธ์ง€๋ฅผ ์•Œ ์ˆ˜ ์—†์–ด ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ์ด๋‹ค. ๐Ÿงฏ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ..
[JavaScript] ๋ฌดํ•œ ์Šคํฌ๋กค ๊ตฌํ˜„ํ•˜๊ธฐ(Intersection Observer API)
ยท
Frontend/JavaScript
๋ฌดํ•œ ์Šคํฌ๋กค(Infinite Scroll)์ด๋ž€? ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€ ํ•˜๋‹จ์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ, ์ฝ˜ํ…์ธ ๊ฐ€ ๊ณ„์† ๋กœ๋“œ๋˜๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜(UX) ๋ฐฉ์‹์ด๋‹ค. ํ•œ ํŽ˜์ด์ง€ ์•„๋ž˜๋กœ ์Šคํฌ๋กค ํ•˜๋ฉด ๋์—†์ด ์ƒˆ๋กœ์šด ํ™”๋ฉด์„ ๋ณด์—ฌ์ฃผ๊ฒŒ ๋˜๊ณ  ์ด๋กœ ์ธํ•ด ๋งŽ์€ ์–‘์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์Šคํฌ๋กค ํ•ด์„œ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ํŽ˜์ด์ง€๋„ค์ด์…˜์ด ์•„๋‹Œ ๋ฌดํ•œ ์Šคํฌ๋กค๋กœ ๊ตฌํ˜„ํ•˜๋ ค๋Š” ์ด์œ โ“ ์ƒํ’ˆ ๋ชฉ๋ก์—์„œ ์ƒํ’ˆ์„ ๋ณด์—ฌ์ฃผ๊ณ ์ž ํ•  ๋•Œ ํŽ˜์ด์ง€๋„ค์ด์…˜, ๋ฌดํ•œ ์Šคํฌ๋กค ์ค‘ ๋ฌด์—‡์ด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๋”์šฑ ์ข‹๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„์ง€ ๊ณ ๋ฏผํ•œ ๋์— ๋ชจ๋ฐ”์ผ ํ™˜๊ฒฝ์„ ๊ณ ๋ คํ•ด์„œ ๋ฌดํ•œ ์Šคํฌ๋กค์„ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.(์ฐจํ›„์— ํ”„๋กœ์ ํŠธ๋ฅผ ๋ฐ˜์‘ํ˜•์œผ๋กœ ๋ฆฌํŒฉํ„ฐ๋ง ํ•  ๊ณ„ํš๐Ÿ™‡๐Ÿป) ๋˜ํ•œ, ๋‹ค์Œ ์ƒํ’ˆ์„ ๋ณด๊ธฐ ์œ„ํ•œ ์‚ฌ์šฉ์ž์˜ ํด๋ฆญ์„ ์ตœ์†Œํ™”ํ•˜๊ณ  ๋” ์‰ฝ๊ฒŒ ๋‹ค์–‘ํ•œ ์ƒํ’ˆ์„ ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ํŒ๋‹จํ–ˆ๋‹ค. ๊ตฌํ˜„ํ•˜๋Š” ๊ณผ์ • ๋ฌดํ•œ ์Šคํฌ๋กค์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์Šคํฌ..
[React] [Immer] "An immer producer returned a new value and modified its draft. Either return a new value or modify the draft." ์—๋Ÿฌ ํ•ด๊ฒฐ
ยท
Frontend/React
๐Ÿ”ฅ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ 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 ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™๋Š”๋‹ค. ์ฆ‰, ์œ„์˜ ์ฝ”๋“œ๋Š” ๊ธฐ์กด..
[Axios] Axios ์ธํ„ฐ์…‰ํ„ฐ ์ ์šฉํ•˜๊ธฐ
ยท
Frontend/JavaScript
์ธํ„ฐ์…‰ํ„ฐ(Interceptors)๋ž€? then ๋˜๋Š” catch๋กœ ์ฒ˜๋ฆฌ๋˜๊ธฐ ์ „์— ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๊ฐ€๋กœ์ฑŒ ์ˆ˜ ์žˆ๋‹ค. Axios ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์ ์šฉํ•˜๋ ค๋Š” ์ด์œ โ“ ํ† ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์„œ๋ฒ„์— ํ† ํฐ ์ธ์ฆ์„ ํ•„์š”๋กœ ํ•˜๋Š” API ์š”์ฒญ์„ ํ• ๋•Œ๋งˆ๋‹ค HTTP Authorization ์š”์ฒญ ํ—ค๋”์— ํ† ํฐ์„ ๋„ฃ์–ด์ค˜์•ผํ•˜๊ณ  401(Unauthorized) ์—๋Ÿฌ๊ฐ€ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋“ค์–ด์˜ค๋ฉด ํ† ํฐ์„ ๊ฐฑ์‹ ํ•ด์ค€ ํ›„ ์žฌ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ณผ์ •์„ ํ•œ ๊ณณ์—์„œ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•˜์—ฌ ์ค‘๋ณต ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด Axios ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์ ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ง€์ • config๋กœ ์ƒˆ๋กœ์šด Axios ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋‹ˆ ๋”์šฑ ํŽธ๋ฆฌํ–ˆ๋‹ค. (baseURL, timeout ์„ค์ •) ์ ์šฉํ•˜๋Š” ๊ณผ์ • 1) Axios ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ const instanc..
[JavaScript] ์ •๊ทœ ํ‘œํ˜„์‹ ์•ˆ์— ๋™์ ์œผ๋กœ ๋ณ€์ˆ˜๋ฅผ ๋„ฃ๋Š” ๋ฐฉ๋ฒ•
ยท
Frontend/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() ๋ฉ”์„œ๋“œ๋Š” ๋ฌธ์ž์—ด์ด ์ •๊ทœ์‹๊ณผ ๋งค์น˜๋˜๋Š”..
[JavaScript] ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋กœ ํ(Queue) ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•
ยท
Frontend/JavaScript
ํ(Queue)๋ž€? ํ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ผ์‹œ์ ์œผ๋กœ ์ €์žฅํ•˜๋Š” ์ž๋ฃŒ๊ตฌ์กฐ ์ค‘ ํ•˜๋‚˜๋กœ, ๋จผ์ € ์ž…๋ ฅ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋จผ์ € ์ถœ๋ ฅ๋˜๋Š” "์„ ์ž…์„ ์ถœ(FIFO: First-In-First-Out)" ์›์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ํ(Queue)์˜ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• 2๊ฐ€์ง€ ํ๋Š” ๋ฐฐ์—ด(Array)์ด๋‚˜ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Linked List)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 1๏ธโƒฃ ๋ฐฐ์—ด ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ํฌ๊ธฐ๊ฐ€ ๊ณ ์ •๋˜์–ด ์žˆ์–ด์„œ ๋ฐ์ดํ„ฐ์˜ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐ์— ์ œํ•œ์ด ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, ์—ฐ์‚ฐ ์†๋„๊ฐ€ ๋น ๋ฆ…๋‹ˆ๋‹ค. 2๏ธโƒฃ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, ํฌ๊ธฐ์— ์ œํ•œ์ด ์—†์–ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์œ ๋™์ ์œผ๋กœ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์—ฐ์‚ฐ ์†๋„๊ฐ€ ๋Š๋ฆฝ๋‹ˆ๋‹ค. ๐Ÿง ๋ฐฐ์—ด๋กœ ํ(Queue)๋ฅผ ๊ตฌํ˜„ํ•ด๋„ ๋˜์ง€๋งŒ ๊ตณ์ด ? ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋กœ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ์ด์œ  JavaScript์—์„œ ๋ฐฐ์—ด์„ ์‚ฌ์šฉ..
[React/Axios] ๐Ÿคฌ Axios message: 'Network Error'(CORS ์˜ค๋ฅ˜)
ยท
Frontend/React
๐Ÿšจ ์˜ค๋ฅ˜ ๋ฐœ์ƒ 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' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๊ธ€ ๋ชฉ๋ก