๋
ธ์
ํด๋ก ์ฝ๋ฉ ๊ฐ์ธ ํ๋ก์ ํธ์ ๋๋ฌด ํ์ ์์ ๋๋จธ์ง 5์ฃผ์ฐจ TIL์ ๋ชฐ์์ ์ค๋ ์ฐ๋ ๋ ๋ฐ์ฑํด~๐ฅฒ
์ ๋ฒ์ฃผ ์ํ์๋ชฉ๊ธ์ ์ง์ง ๋จธ๋ฆฟ์์ ๋
ธ์
์๊ฐ ๋ฟ์ด์๋ค...
ํ๋๋ฅผ ํด๊ฒฐํ๋ฉด ๋ ๋ค๋ฅธ ํ๋์ ๋ถ๋ชํ๊ณ ...์ข๋ง ์ฝ๋๋ฅผ ๊ณ ์น๋ฉด ๋ฐ๋ก ์ค๋ฅ๊ฐ ๋จ๊ณ ...
๊ทธ๋๋ ์ผ๋จ ๊ธฐ๋ณธ ๊ตฌํ ์ฌํญ ๊ตฌํ์ ์ฑ๊ณตํ๋ค. ์ฝ๋๊ฐ ๋งค์ฐ ์ง์ ๋ถํ๊ณ ๋ง์ ๋ค์ง์์ง๋ง ๊ทธ๋๋ ๋ฐ๋๋ผ JS์ ์กฐ๊ธ์ ์ต์ํด์ก๋ค. ๊ทธ๋ฆฌ๊ณ ์ด์ฌํ ๋ชฐ์
ํ ๋ ์์ ์๊ฒ๋ ์ฌ์ฌํ ์๋ก์ ๋ง์ ๊ฑด๋ค๊ณ ์ถ๋ค.
์ด๋ฒ TIL์ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ ์ด๋ ต๊ณ ๋งํ๋ ๋ถ๋ถ์ ์ ๋ฆฌํจ์ผ๋ก์จ ๋ฌธ์ ๋ฅผ ์ง์ด๋ณด๋๋ก ํ๊ฒ ๋ค.
- ํ๋ฉด ์ข์ธก์ ๋ฌธ์ ๋ ๋๋ง
- ๋ฌธ์๋ ํธ๋ฆฌ ๊ตฌ์กฐ๋ก ๋ฃจํธ ๋ฌธ์๋ ํ์ ๋ฌธ์๋ฅผ ๊ฐ์ง
- ๊ฐ ๋ฌธ์๋ ์ถ๊ฐ์ ์ญ์ ๊ธฐ๋ฅ์ ๊ฐ์ง
- ์ถ๊ฐ ์ ํ์ ๋ฌธ์๊ฐ ์ถ๊ฐ๋จ
- ์ญ์ ์ ๋ฌธ์๊ฐ ์ญ์ ๋๊ณ , ํ์ ๋ฌธ์๋ ๋ฃจํธ ๋ฌธ์๊ฐ ๋จ
- ํ๋ฉด ์ฐ์ธก์๋ ํธ์ง๊ธฐ๊ฐ ์์ผ๋ฉฐ, ํธ์ง๊ธฐ์ ์ ๋ ฅ ๋ด์ฉ์ ์๋์ผ๋ก ์๋ฒ์ ์ ์ฅ๋จ
- History API๋ฅผ ์ด์ฉํด SPA ํํ๋ก ๊ตฌํ
- ๊ธฐ๋ณธ์ ๋ฌธ์๊ฐ ์ ํ๋์ง ์์ ์ํ
- ๋ฌธ์ id๋ฅผ ๊ฐ์ง url๋ก ์ ์ ์ ํด๋น ๋ฌธ์๋ฅผ ํธ์ง๊ธฐ์ ๋ก๋ฉ
๋ ธ์ ์ ๋ณด๋ฉด ๋ฃจํธ ๋ฌธ์์ ํ์ ๋ฌธ์๋ค๋ก ๋ฉ๋ด ๊ตฌ์ฑ์ด ๊ฐ๋ฅํ ๊ฒ์ ํ์ธํ ์ ์๋ค. ์ด๋ฌํ ๋ฉ๋ด ๊ตฌ์ฑ์ ul๊ณผ li ํ๊ทธ์ ์กฐํฉ์ผ๋ก ์์ฑํ ์ ์๋ค.
<ul>
<li>๋ฃจํธ ๋ฌธ์1</li>
<li>๋ฃจํธ ๋ฌธ์2</li>
<ul>
<li>ํ์ ๋ฌธ์ 1</li>
<li>ํ์ ๋ฌธ์ 2</li>
</ul>
</ul>
๊ณ์ํด์ ๋ฐ๋ณต๋๋ ๊ตฌ์กฐ์ด๋ฏ๋ก mapํจ์์ ์ฌ๊ท ํจ์๋ฅผ ํตํด ๊ตฌํํด๋ณด์๋ค.
์ฒ์์๋ map ๋ง๊ณ forEach๋ฅผ ์ด์ฉํด ๊ตฌํํ๋ คํ์ผ๋ ๊ณ์ํด์ undefined๊ฐ ์ถ๋ ฅ๋์๋ค.
๋ด๊ฐ map๊ณผ forEach์ ์ฐจ์ด๋ฅผ ์์ง ์ ํํ ์ดํดํ์ง ๋ชปํ๋ ํ์ด์๋ค.
map์ ๊ฒฝ์ฐ ์์ ๋ ์๋ก์ด ๋ฐฐ์ด์ ๋ฐํํ๋ ๋ฐ๋ฉด์ forEach๋ ์ด๋ ํ ๊ฐ๋ ๋ฐํํ์ง์๋๋ค. ๊ทธ๋์ push๋ก ์๋ก์ด ๋ณ์์ ์ถ๊ฐํด์ค์ผ๋ง ์๋ก์ด ๋ฐฐ์ด์ ์ป์ด๋ผ ์ ์๋ค.
map()๊ณผ forEach()
์ฌ๋ฌ๋ฒ์ ์๋ ๋์ Tree View๋ฅผ ๊ตฌํํด๋ด๋๋ฐ ์ฑ๊ณตํ๋ค.
// tree menu ๋ง๋ค๊ธฐ : map + ์ฌ๊ท
const createTreeView = (document) => {
return document
.map(
({ id, title, documents }) => `
<li data-id=${id} class="documentItem">${
documents.length > 0
? `<span class="hasChild">${title}</span>`
: `${title}`
}
<button class="createDoc"><i class="fas fa-folder-plus"></i></button>
<button class="removeDoc"><i class="fas fa-trash-alt"></i></button>
${
documents.length > 0
? `<ul class="hasChildUl">${createTreeView(documents)}</ul>`
: ""
}
</li>`
)
.join("");
};
์ถ๊ฐ์ ์ญ์ ๊ธฐ๋ฅ ๊ฐ์ ๊ฒฝ์ฐ์๋ TodoApp์ ๋ง๋ค๋ฉฐ ์ฐ์ตํด ๋ณธ ์ ์ด ์์ด ๋๋ฆ ์ฝ๊ฒ ๊ตฌํํ๋ ๊ฒ ๊ฐ๋ค.
์ด๋ฒคํธ ์์์ ์ฌ์ฉํ์ฌ className์ด ์ผ์นํ๋ ๊ฒฝ์ฐ, ํจ์์ id๊ฐ์ ๋๊ฒจ๋ฒ๋ฆฌ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค.
ํจ์์ ๊ฒฝ์ฐ๋ DocumentsPage๋ผ๋ ์์ ์ปดํฌ๋ํธ์์ ์ ์ํด์ฃผ์๋ค.
๊ตฌํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
$documentList.addEventListener("click", (e) => {
const $li = e.target.closest("li");
if ($li) {
const { id } = $li.dataset;
const $button = e.target.closest("button");
if (e.target.className === "documentItem") {
onSelect(id);
} else if ($button.className === "createDoc") {
onCreate(id);
} else if ($button.className === "removeDoc") {
onRemove(id);
}
}
});
๋ํ, e.target.dataset, e.target.closest ๋ฑ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ํ๊ฒ์ ์์ฑ๋ ์๋ฒฝํ ๊ณต๋ถํด ์ ํ์ฉํด์ผํจ์ ๋๊ผ๋ค.
ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ ๊ฐ์ฅ ์ด๋ ค์ ๋ ๊ฒ์ ์ปดํฌ๋ํธ ๊ตฌ์กฐ๋ก ์ฌ๋ฌ ๊ธฐ๋ฅ๋ค์ ์ชผ๊ฐ๋ ๊ณผ์ ์ด์๋ค.
์๊ฐ์ ํ์ ๋์ด์๊ณ , ๋จธ๋ฆฟ์์ ์ด๋ฐ์์ผ๋ก ๊ตฌ์ฑํด์ผ๊ฒ ๋ค ์ด๋ฐ ์๊ฐ๋ง ๊ฐ์ง๊ณ ์ฝ๋ฉ์ ๋ค์ด๊ฐ๋ ๊ตฌ์กฐ๊ฐ ๋งค์ฐ ๋นํจ์จ์ ์ด์๋ค...
์๋ ์ฒ์ ์๊ฐ์ DocumentList ์ปดํฌ๋ํธ(=ํธ๋ฆฌ ๊ตฌ์กฐ์ document ๋ฆฌ์คํธ๊ฐ ๋ค์ด์์)๋ฅผ DocumentsPage(=์ข์ธก navBar) ์ปดํฌ๋ํธ์ ๋ถ๋ฌ์ค๊ณ ,
Editor(=ํธ์ง๊ธฐ) ์ปดํฌ๋ํธ๋ฅผ DocumentEditPage(=์ฐ์ธก ํธ์ง๊ธฐ ํ์ด์ง)์ ๋ถ๋ฌ์
App ์ปดํฌ๋ํธ์์ DocumentsPage, DocumentEditPage ์ปดํฌ๋ํธ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ
์ด ๋ชฉ์ ์ด์๋ค.
๊ทธ๋ฐ๋ฐ ์ฝ๋ฉ์ ํ๋ค๋ณด๋, DocumentEditPage์ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค DocumentsPage๋ฅผ ์ฌ๋ ๋๋ง
ํด์ผํ๋ค๋ณด๋ DocumentsPage ์ปดํฌ๋ํธ๋ฅผ DocumentEditPage์์ ๊ด๋ฆฌ
ํ ์ ๋ฐ์ ์๋ ๊ทธ๋ฐ ๊ตฌ์กฐ๊ฐ ๋์ด๋ฒ๋ ธ๋ค...
๋ญ๊ฐ ๋ง์ ์ปดํฌ๋ํธ๋ค์ด ๋๋ฌด ์ฝํ๊ณ ์ฝํ ์ด๋ ๊ฒ ํ๋๊ฒ ๋ง๋ ์ถ์ ์๊ฐ์ด ๊ณ์ ๋ค์๋ค...
์๊ฐ์ด ํ์ ๋์ด์๋ค๋ณด๋ ์ผ๋จ ๊ตฌํ์๋ง ์ด์ ์ ๋ง์ถฐ ์ด๋ป๊ฒ๋ ๊ตฌํํด๋ด๊ธด ํ๋๋ฐ ๋ง์กฑ์ค๋ฝ์ง ์์๋ค...๐ต
๊ทธ๋ฆฌ๊ณ ์์ง state๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒ๋ ํ์คํ ์ดํดํ์ง๋ชปํ ๊ฒ ๊ฐ๋ค...
๊ณ์ํด์ ํ๋ก์ ํธ๋ฅผ ๋ฆฌํฉํ ๋งํ๋ ๊ณผ์ ์ ๊ฑฐ์ณ์ผ๊ฒ ๋ค...!!!๐ฅ
SPA ํํ์ ๊ฒฝ์ฐ ๋ชจ๋ ์ ์ ๋ฆฌ์์ค๋ฅผ ์ต์ด์ ํ๋ฒ ๋ค์ด๋ก๋ํ๊ณ , AJAX๋ฅผ ์ด์ฉํด ํ์ด์ง ๊ฐฑ์ ์ ํ์ํ ๋ฐ์ดํฐ๋ง ๋ฐ์ ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง ์ฌ๋ ๋๋งํ๋ ๊ฒ์ ๋งํ๋ค.
์ด๋ฌํ ๊ฒฝ์ฐ ์ ์ฒด์ ์ธ ํธ๋ํฝ์ด ๊ฐ์ํ๊ณ ์ฌ์ฉ์ ๊ฒฝํ์ ํฅ์์ํฌ ์ ์์ง๋ง, url์ด ๋ณ๊ฒฝ๋์ง์์ผ๋ฏ๋ก ํ์คํ ๋ฆฌ ๊ด๋ฆฌ(๋ค๋ก ๊ฐ๊ธฐ, ์์ผ๋ก ๊ฐ๊ธฐ ๋ฑ)๊ฐ ์ด๋ ต๋ค.
์ด๋ฅผ ํด๊ฒฐํด์ฃผ๋ ๊ฒ์ด ๋ฐ๋ก history API์ด๋ค. history์ pushState ๋ฉ์๋
๋ ์ฃผ์์ฐฝ์ url์ ๋ณ๊ฒฝํ๊ณ url์ history์ ์ถ๊ฐํ๋ค. replaceState ๋ฉ์๋
์ ๊ฒฝ์ฐ๋ ํ์ฌ์ history๋ฅผ ์์ ํด ์ํ๋ url๋ก ์
๋ฐ์ดํธํด์ค๋ค.
์ด๋ฒ ํ๋ก์ ํธ์์๋ ํน์ document๋ฅผ ์ ํํ์ ๊ฒฝ์ฐ์ ์๋ก์ด ๋ฌธ์๋ฅผ ์์ฑํ์ ๊ฒฝ์ฐ
push๋ฅผ ์ด์ฉํ์ฌ url์ ํ์ฌ document์ id๋ก ๋ณ๊ฒฝํด์ฃผ๋ ์ฝ๋๋ฅผ ์์ฑํ์๋ค.
onSelect: async (id) => {
push(`/documents/${id}`);
},
onCreate: async (id) => {
const createdDoc = await request(`/documents`, {
method: "POST",
body: JSON.stringify({
title: "์๋ก์ด ๋ฌธ์",
parent: id,
}),
});
push(`/documents/${createdDoc.id}`);
this.render();
}
์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์ pushState์ replaceState ๋ฉ์๋๋ ์ฃผ์์ฐฝ์ url์ ๋ณ๊ฒฝํ ๋ฟ HTTP ์์ฒญ์ด ์๋ฒ๋ก ์ ์ก๋์ง๋ ์๋๋ค. ๋ฐ๋ผ์ request๋ฅผ ์ด์ฉํด ์๋ฒ์ ์์ฒญ์ ๋ณด๋ธ ํ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํด ์ฌ๋ ๋๋งํด์ฃผ๋ ๊ณผ์ ์ด ํ์ํ๋ค.
DocumentEditPage์์ ๋ฌธ์์ ํ์ดํ์ ๋ณ๊ฒฝํ๊ณ ๊ทธ ๋ณ๊ฒฝํ ๋ด์ฉ์ผ๋ก DocumentsPage๊ฐ ์ฌ๋ ๋๋ง๋์ด ๋ณ๊ฒฝ๋ ํ์ดํ์ด ์ ์ฉ๋์ด์ผํ๋๋ฐ ์์ ๊ณผ์ ์ ์ ๋๋ก ์ํด์ค์ ์ฉ์ฉ๋งจ ๊ธฐ์ต์ด ๋๋ค.
์ฌ์ค setState๋ฅผ ์ด์ฉํด ๋ ๋๋งํ๋ ๊ณผ์ ์ ํ๋ฒ์ ๊ด๋ฆฌํ๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ์๋ฐ, ์์ง ์ปดํฌ๋ํธ๊ฐ ์ ๊ธฐ์ ์ผ๋ก ์ฐ๊ฒฐ๋์ด์๋ ๊ตฌ์กฐ๋ฅผ ์ ํํ ํ์
ํ์ง ๋ชปํด์ ์ ์ฉํ์ง๋ชปํ๋ค...
๊ฐ์๋ฅผ ๋ณต์ตํ๋ฉฐ ๋ค์ ์ฒ์๋ถํฐ ์์ํด๋ด์ผ๊ฒ ๋ค!!!
1. DocumentList Toggle ๊ด๋ จ
- ์ด๋ฆฌ๋ ํ ๊ธ์ ์ ์ ๋์ํ๋, ํ์ด์ง ์ถ๊ฐ ๋๋ ์ญ์ ์ ํ ๊ธ์ด ๋ค์ ๋ซํ๋ ํ์ ๋ฐ์
2. ์ญ์ ๋ฒํผ ๊ธฐ๋ฅ ๊ด๋ จ
- ์์ document ์ญ์ ์ ํด๋น document์ ํ์ document๊ฐ ์ญ์ ๋ document์ ์์น๋ก ๊ฐ์ง์๊ณ , ๋ฃจํธ document๋ก ๊ฐ๋ ํ์
- ํ์ฌ ์ ํ๋ ๋ฌธ์ ์ญ์ ์ editor๊ฐ ์์ด์ง์ง์๊ณ ๋จ์์๋ ํ์(=/documents/๋ก ๋ ๋๋ง์ด ์๋๋ ๋ฌธ์ )
3. Document onSelect ๊ด๋ จ
- ์ด๋ฏธ ์ ํ๋์ด์๋ document๋ฅผ ๋ ์ ํ ์ ์ฝ์์ฐฝ์ ์ค๋ฅ ๋ฐ์, ๊ธฐ๋ฅ์ ์ ์ ๋์
๋ด๊ฐ ์๊ณ ์๋ค๊ณ ์๊ฐํ๋ ๋ถ๋ถ๋ ์ง์ ๊ตฌํํด๋ณด๋ ์ง์ ์ผ๋ก ์๊ณ ์๋๊ฒ ์๋์๊ณ ...
์๊ฐ๋ณด๋ค ์๊ฐ์ ๋นจ๋ฆฌ ํ๋ฌ๊ฐ๊ณ ์๊ฐ์ง๋ ๋ชปํ ๋ถ๋ถ์์ ๋ง์ ์ค๋ฅ๋ฅผ ๊ฒฝํํ๋ค...
๊ทธ๋๋ ๋ฐ๋๋ผ JS์ ์กฐ๊ธ์ ์ต์ํด์ก๊ณ , ์ฑ์ฅํด๋๊ฐ์ ๋๋ ์ ์์๋ค. ์์ง ๊ฐ ๊ธธ์ด ๋ฉ๊ธดํ์ง๋ง...ใ
ใ
๋ํ, ์ด๋ฒ ํ๋ก์ ํธ๋ ์๋ํ๋ ์ฝ๋๋ฅผ ๋ง๋ค๊ธฐ์ ์ง์คํ๊ธด ํ์ง๋ง, ์ฝ๋๋ ์ฝ๊ฒ ์ง์ ๋ถํด์ก๊ณ ๋ณ์๋ช
๋์ค์ ์ง์ผ์ง๋ผ๋ ์๊ฐ๋ ์ด๋ฒ ํ๋ก์ ํธ๋ฅผ ๊ณ๊ธฐ๋ก ๋ฒ๋ฆฌ๊ธฐ๋ก ํ๋ค.
๊ทธ๋ฆฌ๊ณ ์ค๊ณ ๊ณผ์ ์ด ์ ๋ง ์ค์ํจ์ ๋๊ผ๋ค. ์ ์ด๋ ๊ฒ ์ด๋ ๊ฒ ํ๋ฉด ๋๊ฒ ์ง๋ผ๊ณ ์๊ฐํ๊ณ ๋ฐ๋ก ์ฝ๋ฉ์ ์์ํ๋ ๊ฒ์ด ๋ฌธ์ ์๋ค. ๋ค์ ํ๋ก์ ํธ ๋๋ ์ง์ง ์ธ์ธํ ๋ถ๋ถ๊น์ง ์ ํํ ์๊ณ ์ค๊ณํ ํ์ ์ฝ๋ฉ์ ์์ํด์ผ๊ฒ ๋ค.
์ฝ๋ฉํ๋ฉด์ ๊ธธ์ ์์ง ์๋๋ก...๐ฅฒ
๋ง์ง๋ง์ผ๋ก ๊ผญ ๋ฆฌํฉํ ๋งํ๊ธฐ!!!!๊ฐ ๋์ ๋ค์ ๋ชฉํ์ด๋ค!!!๐ฅ๐ฅ๐ฅ