์ „์ฒด ๊ธ€

Deployment

[Netlify] FirebaseError: Firebase: Error (auth/invalid-api-key). ์—๋Ÿฌ ํ•ด๊ฒฐ

๐Ÿ”ฅ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ Uncaught FirebaseError: Firebase: Error (auth/invalid-api-key). ๋กœ์ปฌ์—์„œ๋Š” ์ž˜ ๋™์ž‘ํ–ˆ์ง€๋งŒ Netlify์— ๋ฐฐํฌ ํ›„ ํ™•์ธํ•ด๋ณด๋‹ˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. ๋ฐฐํฌํ•  ๋•Œ ์ฐธ๊ณ ํ•œ ์‚ฌ์ดํŠธ(https://create-react-app.dev/docs/deployment#netlify) ์›์ธ ๋ถ„์„ ํ•ด๋‹น ์—๋Ÿฌ์— ๋Œ€ํ•ด ๊ธ€์„ ์“ด ์—ฌ๋Ÿฌ ๋ธ”๋กœ๊ทธ๋ฅผ ์ฐพ์•„์„œ ์ฝ์–ด๋ณด๋‹ˆ ๋‹ค์Œ์˜ ๊ฒฝ์šฐ์— ์ด๋Ÿฌํ•œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. .env ํŒŒ์ผ์ด ๋ฃจํŠธ์— ์—†๋Š” ๊ฒฝ์šฐ API ํ‚ค๊ฐ€ ์ž˜๋ชป๋œ ๊ฒฝ์šฐ firebaseConfig๋ฅผ exportํ•˜๊ณ , ๋‹ค๋ฅธ JS ํŒŒ์ผ์—์„œ import ํ•  ๊ฒฝ์šฐ ๋กœ์ปฌ์—์„œ๋Š” ์ž˜ ๋™์ž‘ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— Netlify์—์„œ ๋‚ด๊ฐ€ ์„ค์ •ํ•œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ œ๋Œ€๋กœ ์ธ์‹ํ•˜์ง€ ๋ชปํ•˜๊ณ  ์žˆ์„ ๊ฒƒ ๊ฐ™..

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) =>..

Backend/Sequelize

[Sequelize] Sequelize findAndCountAll ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ ์‹œ count๊ฐ€ ์˜ˆ์ƒ๋ณด๋‹ค ๋” ๋งŽ์ด ์นด์šดํŒ… ๋˜๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ

๐Ÿ”ฅ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ getBoards ํ•จ์ˆ˜๋Š” ์นดํ…Œ๊ณ ๋ฆฌ์— ํ•ด๋‹นํ•˜๋Š” ๊ฒŒ์‹œ๊ธ€ ์ „์ฒด๋ฅผ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๋‹ค. (๊ฐ€๋…์„ฑ์„ ์œ„ํ•ด ๊ด€๋ จ ์—†๋Š” ์ฝ”๋“œ ์ผ๋ถ€ ์ƒ๋žต) /* ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ํ•จ์ˆ˜๋“ค(์ฐธ๊ณ ์šฉ) const getPagination = (page, size) => { const limit = size ? +size : 10; // ๊ฐ€์ ธ์˜ฌ ๋ฐ์ดํ„ฐ ์–‘ const offset = page ? page * limit : 0; // ๊ฐ€์ ธ์˜ฌ ๋ฐ์ดํ„ฐ์˜ ์ดˆ๊ธฐ ์œ„์น˜๊ฐ’ return { limit, offset }; }; const getPagingData = (data, page, limit) => { // count: where ์ ˆ, ์—ฐ๊ฒฐ ๊ด€๊ณ„ ๋“ฑ์˜ ์กฐ๊ฑด์— ๋ถ€ํ•ฉํ•˜๋Š” ๋ ˆ์ฝ”๋“œ์˜ ์ „์ฒด ๊ฐœ์ˆ˜ // rows: where ์ ˆ, ์—ฐ๊ฒฐ ๊ด€..

Frontend/React

[React] onKeyDown, onKeyUp ์ด๋ฒคํŠธ, ํ•œ๊ธ€ ์ž…๋ ฅ ์‹œ ํ•จ์ˆ˜ ๋‘ ๋ฒˆ ์‹คํ–‰๋˜๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ

๐Ÿ”ฅ ๋ฐœ์ƒํ•œ ๋ฌธ์ œ ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ์—”ํ„ฐ(Enter) ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋ฉด ๋ชฉ๋ก์— ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€๋˜๊ณ  input ์ฐฝ์€ ๋น„์›Œ์ง€๋„๋ก ๊ตฌํ˜„ํ–ˆ๋Š”๋ฐ ์™ ์ง€ ๋ชจ๋ฅด๊ฒŒ ํ•จ์ˆ˜๊ฐ€ ๋‘ ๋ฒˆ ์‹คํ–‰๋˜๋ฉด์„œ ๊ธฐ์กด ํ…์ŠคํŠธ์˜ ๋งˆ์ง€๋ง‰ ๊ธ€์ž๊ฐ€ ๋ชฉ๋ก์— ์ถ”๊ฐ€๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹คโ—๏ธ ์›์ธ ๋ถ„์„ ๊ฒ€์ƒ‰ํ•ด๋ณธ ๊ฒฐ๊ณผ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋Š” ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ•œ๊ธ€์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. (์˜์–ด๋กœ ์ž…๋ ฅํ•˜๋ฉด ํ‚ค ์ด๋ฒคํŠธ๊ฐ€ ์ค‘๋ณต์œผ๋กœ ๋ฐœ์ƒํ•˜์ง€ โŒ) ๊ตฌ์ฒด์ ์œผ๋กœ ์œ„ GIF๋ฅผ ๋ณด๋ฉด ํ•œ๊ธ€ ์ž…๋ ฅ ์‹œ ์ž…๋ ฅ ์ค‘์ธ ๊ธ€์ž ์•„๋ž˜ ๊ฒ€์€ ๋ฐ‘์ค„์ด ์ƒ๊ธฐ๋Š”๋ฐ ํ•ด๋‹น ๋ฐ‘์ค„์ด ์žˆ๋Š” ์ƒํ™ฉ์—์„œ ํ‚ค ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ํ•จ์ˆ˜๊ฐ€ ๋‘ ๋ฒˆ ์‹คํ–‰๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ํ•œ๊ธ€์˜ ๊ฒฝ์šฐ ์ž์Œ๊ณผ ๋ชจ์Œ์˜ ์กฐํ•ฉ์œผ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ์กฐํ•ฉ ๋ฌธ์ž์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ธ€์ž๊ฐ€ ์กฐํ•ฉ ์ค‘์ธ์ง€ ์กฐํ•ฉ์ด ๋๋‚œ ์ƒํƒœ์ธ์ง€๋ฅผ ์•Œ ์ˆ˜ ์—†์–ด ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ์ด๋‹ค. ๐Ÿงฏ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ..

Frontend/JavaScript

[JavaScript] ๋ฌดํ•œ ์Šคํฌ๋กค ๊ตฌํ˜„ํ•˜๊ธฐ(Intersection Observer API)

๋ฌดํ•œ ์Šคํฌ๋กค(Infinite Scroll)์ด๋ž€? ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€ ํ•˜๋‹จ์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ, ์ฝ˜ํ…์ธ ๊ฐ€ ๊ณ„์† ๋กœ๋“œ๋˜๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜(UX) ๋ฐฉ์‹์ด๋‹ค. ํ•œ ํŽ˜์ด์ง€ ์•„๋ž˜๋กœ ์Šคํฌ๋กค ํ•˜๋ฉด ๋์—†์ด ์ƒˆ๋กœ์šด ํ™”๋ฉด์„ ๋ณด์—ฌ์ฃผ๊ฒŒ ๋˜๊ณ  ์ด๋กœ ์ธํ•ด ๋งŽ์€ ์–‘์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์Šคํฌ๋กค ํ•ด์„œ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ํŽ˜์ด์ง€๋„ค์ด์…˜์ด ์•„๋‹Œ ๋ฌดํ•œ ์Šคํฌ๋กค๋กœ ๊ตฌํ˜„ํ•˜๋ ค๋Š” ์ด์œ โ“ ์ƒํ’ˆ ๋ชฉ๋ก์—์„œ ์ƒํ’ˆ์„ ๋ณด์—ฌ์ฃผ๊ณ ์ž ํ•  ๋•Œ ํŽ˜์ด์ง€๋„ค์ด์…˜, ๋ฌดํ•œ ์Šคํฌ๋กค ์ค‘ ๋ฌด์—‡์ด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๋”์šฑ ์ข‹๊ฒŒ ํ•  ์ˆ˜ ์žˆ์„์ง€ ๊ณ ๋ฏผํ•œ ๋์— ๋ชจ๋ฐ”์ผ ํ™˜๊ฒฝ์„ ๊ณ ๋ คํ•ด์„œ ๋ฌดํ•œ ์Šคํฌ๋กค์„ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.(์ฐจํ›„์— ํ”„๋กœ์ ํŠธ๋ฅผ ๋ฐ˜์‘ํ˜•์œผ๋กœ ๋ฆฌํŒฉํ„ฐ๋ง ํ•  ๊ณ„ํš๐Ÿ™‡๐Ÿป) ๋˜ํ•œ, ๋‹ค์Œ ์ƒํ’ˆ์„ ๋ณด๊ธฐ ์œ„ํ•œ ์‚ฌ์šฉ์ž์˜ ํด๋ฆญ์„ ์ตœ์†Œํ™”ํ•˜๊ณ  ๋” ์‰ฝ๊ฒŒ ๋‹ค์–‘ํ•œ ์ƒํ’ˆ์„ ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ํŒ๋‹จํ–ˆ๋‹ค. ๊ตฌํ˜„ํ•˜๋Š” ๊ณผ์ • ๋ฌดํ•œ ์Šคํฌ๋กค์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์Šคํฌ..

ํšŒ๊ณ 

[ํšŒ๊ณ ] Ticket Want it!(ํ‹ฐ์ผ“์›์ž‡!) ํ”„๋กœ์ ํŠธ ํšŒ๊ณ 

1์ฐจ ํ”„๋กœ์ ํŠธ ๋ฐœํ‘œ๋ฅผ ๋งˆ์นœ ํ›„ ๋ฆฌํŒฉํ„ฐ๋ง ์‹œ๊ฐ„์„ ๊ฐ€์ง€๋ฉด์„œ ํšŒ๊ณ ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค. ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ ํ”„๋กœ์ ํŠธ ์ฃผ์ œ ์˜จ๋ผ์ธ ํ‹ฐ์ผ“ ๊ตฌ๋งค ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ์‡ผํ•‘๋ชฐ ํ”„๋กœ์ ํŠธ๋ช… ํ‹ฐ์ผ“์›์ž‡!(Ticket Want it!) ์ œ์ž‘ ๊ธฐ๊ฐ„ 2023.04.17 ~ 2023.04.28(1์ฐจ ์ œ์ž‘๊ธฐ๊ฐ„, ์ตœ์†Œ ๊ธฐ๋Šฅ ๊ตฌํ˜„) 2023.04.29 ~ 2023.05.20(2์ฐจ ์ œ์ž‘๊ธฐ๊ฐ„, ๊ธฐ๋Šฅ ์ถ”๊ฐ€ ๋ฐ ๋ฆฌํŒฉํ„ฐ๋ง) ํŒ€ ๊ตฌ์„ฑ ๋‹ด๋‹น ํฌ์ง€์…˜ : ํŒ€์›, ํ”„๋ก ํŠธ์—”๋“œ Frontend(3๋ช…) : ์ด์„ฑํ˜ธ, ์œค์šฐ์ •, ๊น€์œค์ค‘ Backend(3๋ช…) : ์œ ํ•˜์˜, ์ด๋ฏผ์˜, ์ •ํ˜œ๋ฆฐ ๊ธฐ์ˆ  ์Šคํƒ ๊ตฌํ˜„ ๊ธฐ๋Šฅ ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ, ํšŒ์›์ •๋ณด ์ˆ˜์ • ๋ฐ ํƒˆํ‡ด ๋“ฑ ์‚ฌ์šฉ์ž ๊ด€๋ จ CRUD ์ƒํ’ˆ(์ œํ’ˆ) ๊ด€๋ จ CRUD, ์นดํ…Œ๊ณ ๋ฆฌ ๊ด€๋ จ CRUD, ์ฃผ๋ฌธ ๊ด€๋ จ CRUD ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๊ด€๋ จ ๊ธฐ๋Šฅ(์žฅ๋ฐ”๊ตฌ๋‹ˆ..

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..

ํ”„๋ก ํŠธ์—”๋“œ ์—”์ง€๋‹ˆ์–ด
๐ŸŒฑ์„ฑํ˜ธ's ๋ธ”๋กœ๊ทธ