row 번호 자동으로 뽑아주는 함수 만들기
| 번호 | 제목 | 내용 |
---------------------------
1 key1 data1
2 key2 data2
3 key3 data3
4 key4 data4
5 key5 data5
6 key6 data6
7 key7 data7
8 key8 data8
9 key9 data9
10 key10 data10
11 key11 data11
12 key12 data12
......
....
..
- 만들고 싶은 기능 -
만약 위와 같은 테이블을 만들어야 한다고 생각해 보자.
제목과 내용에 들어가는 값들은 어쨌든 key 값들이니 일일이 넣어줘야 할 것이다.
이 부분은 어쩔 수 없으니 넘어가자.
하지만 번호까지 1,2,3,4... 일일이 쓰는 건 너무 프로그래머로서 귀찮다.
또 항목 순서가 바뀌거나, 항목이 추가/삭제되면 번호를 하나씩 밀려서 모두 바꿔줘야 한다.
유지보수까지 생각하니 더욱 귀찮다.
- 방법 구상 -
번호를 자동으로 뽑아주는 방법을 생각해 봤다.
for문 같은 걸 쓸 수도 없다.
그러려면 반복문을 돌리면서 row 를 하나씩 불러와서 번호를 넣어줘야 하는데,
그러기에는 항목마다 데이터 타입이나 이벤트 처리도 각각 다르기 때문이다.
그래서 약간 클래스 변수처럼 쓰는 방법을 생각해 봤다.
화면 전체에서 행 번호 변수 rowNum 을 하나 갖는다.
이 행 번호 변수는 함수 getRowNum() 을 통해서 받아올 수 있다.
대신 번호를 받아올 때마다 번호가 1씩 증가하도록 만든다.
그러면 render() 함수가 실행되면서 화면을 그리는 동안에 그 안에서 getRowNum() 가 실행될 것이다.
행 하나를 그릴 때마다 getRowNum() 를 실행할 것이고,
그때마다 행 번호 변수 rowNum 은 1씩 자동으로 증가할 것이다.
- 코드 -
class MyTable = {
_rowNum = 0;
getRowNum() {
this._rowNum = this._rowNum + 1;
return this._rowNum;
}
// ...
render() {
this._rowNum = 0;
return (
<table>
<tbody>
<tr>
<th>{this.getRowNum()}</th>
<th>{"key1"}</th>
<th>{"data1"}</th>
</tr>
<tr>
<th>{this.getRowNum()}</th>
<th>{"key2"}</th>
<th>{"data2"}</th>
</tr>
<tr>
<th>{this.getRowNum()}</th>
<th>{"key3"}</th>
<th>{"data3"}</th>
</tr>
</tbody>
</table>
);
}
}
이게 될까...? 하면서 반신반의 하며 실행해 봤는데 잘 된다.
'이게 될까...?' 라며 미심쩍어 했던 이유는 render() 함수 안에서
변수를 조작하는 로직이 실행되고 있기 때문이다.
render() 함수 안에서는 되도록 화면을 그리는 작업 외에는 다른 작업을 수행하지 않는 것이 좋다.
그 이유는 사이드 이펙트 때문이다.
https://velog.io/@superlipbalm/blogged-answers-a-mostly-complete-guide-to-react-rendering-behavior
// 렌더 로직은 다음을 수행해서는 안 됩니다.
> 기존 변수 및 객체를 변경할 수 없습니다.
> Math.random() 또는 Date.now() 와 같은 임의의 값을 생성할 수 없습니다.
> 네트워크 요청을 할 수 없습니다.
> state 업데이트를 큐에 추가할 수 없습니다.
// 렌더 로직은 다음을 수행할 수 있습니다.
> 렌더링 도중 새로 생선된 객체 변경
> 오류 발생
> 캐시된 값과 같이 아직 생성되지 않은 데이터에 대한 '지연 초기화'
> https://gist.github.com/sebmarkbage/75f0838967cd003cd7f9ab938eb1958f
render() 함수는 어쨌든 '순수하게' 화면을 그리는 역할만 해야 하고,
화면의 다른 상태나 변수를 건드리면 안 된다.
어쨌든... 에러도 안 나고 심각한 사이드 이펙트처럼 보이지는 않으므로 그냥 쓰기로 했다.
추가)
this._rowNum = 0;
render() 함수 안에서 위 구문을 실행해야 한다.
render() 를 실행할 때마다 _rowNum 의 값을 0으로 초기화하는 역할이다.
왜냐하면 state 나 props 가 바뀌면 render() 함수를 계속 부르는데,
render 를 다시 부르면 행 번호 숫자가 이어서 증가하기 때문이다.
unmount 되었다가 페이지가 새로 로드되지 않는 이상 클래스 변수는 초기화되지 않는다.
따라서 render() 를 부를 때마다 행 번호를 0부터 시작하도록 초기화해줘야 한다.
- 230223 -