๊ณ ๊ฐ ์ ๋ณด๋ฅผ ๋ณด์ฌ์ค
ํ๋ฅผ ๋ง๋ค์ด๋ณด์!
1. ํ๋ฉด

๊ณ ๊ฐ ์ ๋ณด๊ฐ ํ๋ฉด์ ๋ณด์ด๋๋ก ํ๋ฉฐ, ๋งจ ๋์ ์์ ๊ณผ ์ญ์ ๋ฒํผ์ด ๋์ค๋๋ก ๋ง๋ค์ด๋ณผ ๊ฒ์ด๋ค.
2. ์ ์ฒด ์ฝ๋
<table className="sheet">
<colgroup>
{columns.map((data, i) => (
<col key={i} style={{ width: data.width }} />
))}
</colgroup>
<thead>
<tr>
{columns.map((data, i) => (
<th key={i}>
{data.header}
</th>
))}
</tr>
</thead>
<tbody>
{rows.length === 0 ? (
<tr className="empty-row">
<td colSpan={columns.length}>ํ์ํ ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค.</td>
</tr>
) : (
pagedRows.map((row, rIdx) => (
<tr key={row.id ?? startIndex + rIdx} data-grade={row.grade}>
<td>{row.name}</td>
<td>{row.grade}</td>
<td>{row.phone}</td>
<td>{row.code}</td>
<td>{row.note}</td>
<td>
<div className="edit-delete">
<button
className="btn-edit"
onClick={() => handleEdit(row)}
>
์์
</button>
<button
className="btn-delete"
onClick={() => handleDelete(row.id)}
>
์ญ์
</button>
</div>
</td>
</tr>
))
)}
</tbody>
</table>
3. ๊ธฐ๋ณธ ๊ฐ๋
- ํ ์ด๋ธ: ํ๊ณผ ์ด๋ก ๊ตฌ์ฑ๋ ๊ตฌ์กฐํ๋ ๋ฐ์ดํฐ ์งํฉ(ํ ํ์์ ๋ฐ์ดํฐ)์ด๋ค.
- <table> : ํ ์ด๋ธ ํ๊ทธ
- <colgroup> : ํ ์ด๋ธ ๋ด์์ ์ด๊ทธ๋ฃน์ ์ง์
- <col> : <colgruop> ์์์ ์ฌ์ฉํ๋ฉฐ, ํ ์ด๋ธ ์ ์ ์ด(์ธ๋ก๋ฐฉํฅ)์ ๋ํ๋
- <thead> : ๋จธ๋ฆฌ๊ธ, ์ ๋ชฉ์ ๋ฌ๋ฉฐ <table>์ด ๋ถ๋ชจ๊ณ <tr>์ด ์์์
- <tr> : ํ ์ด๋ธ ์ ์ ํ(๊ฐ๋ก๋ฐฉํฅ)์ ๋ํ๋
- <th> : ํ๊ณผ ์ด์ ์ ๋ชฉ์
- <tbody> : ์ค์ ๋ฐ์ดํฐ ๋ด์ฉ์ ์ฑ์(๊ทธ๋ฃนํ)
- <td> : ์ค์ ๋ฐ์ดํฐ ๋ด์ฉ์ ํ๋ํ๋ ์ฑ์
4. ์ฝ๋ ์ค๋ช
const columns = [
{ header: "์ด๋ฆ", accessor: "name", width: 140 },
{ header: "๋ฑ๊ธ", accessor: "grade", width: 100 },
{ header: "์ฐ๋ฝ์ฒ", accessor: "phone", width: 160 },
{ header: "์ด๋์ฝ๋", accessor: "code", width: 100 },
{ header: "๋ฉ๋ชจ", accessor: "note", width: 250 },
{ header: "๊ด๋ฆฌ", accessor: "actions", width: 140 },
];
<colgroup>
{columns.map((data, i) => (
<col key={i} style={{ width: data.width }} />
))}
</colgroup>
colgroup์ ํ ์ด๋ธ ๋ด์์ ์ด๊ทธ๋ฃน์ ์ ์ํ๋ค. ์ฌ๊ธฐ์ columns๋ return ์ธ๋ถ์ ๋ฐ๋ก ์ ์ํด๋๋ค. map ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ด์ ์ง์ ํ๋๋ฐ, map ํจ์๋ ๊ธฐ์กด ๋ฐฐ์ด์ ๊ฐ ์์๋ค์ ์ํ๋ ํน์ ๊ท์น์ด๋ ๋ก์ง์ด ์๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ํตํด ๋ณํํ ํ ๋ณํ๋ ์์๋ค๋ก ๊ตฌ์ฑ๋ ์๋ก์ด ๋ฐฐ์ด์ ๋ง๋๋ ์ญํ ์ ํ๋ค.
์ฝ๋๊ฐ ์ด๋ป๊ฒ ๋์๊ฐ๋์ง ์์ธํ๊ฒ ์ดํด๋ณด์. key์ i๊ฐ 0์ด ๋๋ค. ๊ทธ๋ฌ๋ฉด ์ฒซ๋ฒ์งธ์ธ ์ด๋ฆ์ด ํด๋น๋๊ณ , style์ ์ ์ํด๋ ๋๋น 140์ด ์ค๊ฒ๋๋ค. ์ด ๊ณผ์ ์ด ๋ฐฐ์ด์ด ๋๋ ๋๊น์ง ๋ฐ๋ณตํ๊ฒ ๋๋ค.
data๋ columns์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋๋ก ์์์ ์ผ๋ก ๋ถ์ธ ์ด๋ฆ์ด๋ค. columns๋ ์ด 6๊ฐ๋๊น 6๋ฒ์ ๋ฐ๋ณต์ผ๋ก ์ด์ ๋ง๋ค๊ฑฐ๊ณ , ๊ฐ ์ด์ ํฌ๊ธฐ๋ columns์ ์ง์ ๋ width๋ฅผ ๋ฐ๋ฅผ ๊ฒ์ด๋ค.
<thead>
<tr>
{columns.map((data, i) => (
<th key={i}>
{data.header}
</th>
))}
</tr>
</thead>
thead์ ๋ถ๋ชจ๋ table์ด๊ณ ์์์ tr์ด๋ค. thead๋ ์ ๋ชฉ์ ๋ฌ ๋ ์ ์ด์ค๋ค. ์ ์ด๋ฐ๊ฑธ ๊ตณ์ด ์ ์๊น? ๋ฐ๋ก ํ ์ด๋ธ ๊ตฌ์กฐ๋ฅผ ์๋ฏธ์๊ฒ ๋๋๊ธฐ ์ํจ์ด๋ค. tr์ ํ(๊ฐ๋ก)์ ์๋ฏธํ๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ์์ th๊ฐ ์ง์ ์ด๋ฆ์ด ๋ค์ด๊ฐ๋ ์ญํ ์ ๊ฐ์ง๋ค.
๋์์ ์์ ์ฝ๋์ ๋งค์ฐ ์ ์ฌํ๋ค. colums์ header๋์ ์ ํ ๋ด์ฉ์ ๋ค๊ณ ์์ th์ ๋ฃ๋๋ค.
{/* tbody๋ ์ค์ ๋ฐ์ดํฐ ๋ด์ฉ์ ์ฑ์ด๋ค. thead์ ์๋ฏธ๋ฅผ ๊ตฌ๋ถํ๋ค! */}
<tbody>
{/* ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ผ๋ก ๊ธธ์ด๊ฐ 0์ผ ๋, (๋ง์ผ๋ฉด ์ด๊ฑฐ ์คํํด) : (์๋๋ฉด ์ด๊ฑฐ ์คํํด) */}
{rows.length === 0 ? (
{/* td๋ ์ค์ ๋ฐ์ดํฐ๋ ๋ด์ฉ์ ๋ด์ */}
{/* coldSpan์ ์จ์ ์นธ์ ๋ชจ๋ ํฉ์น ๋ค ํ
์คํธ๋ฅผ ํ์ํจ */}
<tr className="empty-row">
<td colSpan={columns.length}>ํ์ํ ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค.</td>
</tr>
) : (
{/* pagedRows๋ 10๊ฐ๋๊น rIdx๋ 0์์ 9๊ฐ ๋๋ค. */}
pagedRows.map((row, rIdx) => (
{/* ??๋ ๋ ๋ณํฉ ์ฐ์ฐ์์ด๋ค.row.id๊ฐ null์ด๋ฉด startIndex + rIdx๋ฅผ ์ฌ์ฉํ๋ค. */}
{/* row.id๊ฐ ์๋ค๋ฉด row.id๋ฅผ ์ฐ๊ฒ ์ง๋ง, ํน์ ๋ชจ๋ฅด๋ ์์ ์ฅ์น๋ก ์ค์ ํ๋ค. */}
{/* rIdx๋ 0์์ 9, startIndex๋ ๋ง์ฝ 1ํ์ด์ง๋ผ๋ฉด 0์์ ์์, 2ํ์ด์ง๋ผ๋ฉด 10์์ ์์ */}
{/* ๋ค์์ ์ค๋ช
ํ๊ฒ ์ง๋ง, ํ์ด์ง๋ค์ด์
์ด ์ ์ฉ๋์ด์์ด์ ๊ทธ๋ ๋ค. ํ ํ์ด์ง๋น 10๊ฐ๋ง ๋ณด์ด๋๋ก ์ค์ ํ์ */}
{/* tr์ ๊ฐ ๊ฐ๋กํ์ ๋งํด์, key๋ก ๊ฐ ํ์ ๊ตฌ๋ณํจ */}
<tr key={row.id ?? startIndex + rIdx} data-grade={row.grade}>
{/* td๋ ์ค์ ๋ฐ์ดํฐ์ ๋ด์ฉ์ ๋ด์ */}
{/* ์ง์ ํ๋ํ๋ ๋๋ฆฌ๋ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝํ์, ๋ฒํผ ๋ฃ์ด์ผํด์ */}
{/* ๊ฐ ํ์ key์ ๋ง์ถฐ ์ ๋ณด๋ค์ด ๋์ด๋จ */}
<td>{row.name}</td>
<td>{row.grade}</td>
<td>{row.phone}</td>
<td>{row.code}</td>
<td>{row.note}</td>
{/*์์ , ์ญ์ ๋ฒํผ๋ ์์ ๋์ด๋จ*/}
<td>
<div className="edit-delete">
<button
className="btn-edit"
onClick={() => handleEdit(row)}
>
์์
</button>
<button
className="btn-delete"
onClick={() => handleDelete(row.id)}
>
์ญ์
</button>
</div>
</td>
</tr>
))
)}
</tbody>
</table>
</div>