[리액트] table에는 thead와 tbody가 필요해요(feat. react 형님들)
여느때와 같이 리액트 컴포넌트를 만들고 나서 동작을 확인하고 있는데 콘솔창에 다음과 같은 에러가 떴다.
하.. warning 로그가 있으면 뭔가 큰일 날거같고 너무 허접해보이니 생기면 없애는 나에겐 스트레스다. 그러니 한번 해결해보자.
Warning: validateDOMNesting(...): <tr> cannot appear as a child of <table>. Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by the browser.
바로 구글링 해보면 react 상에서 table를 쓸때에는 되도록 thead 와 tbody 태그를 써서 해야한다고 되어있다. thead와 tbody 태그를 넣어주니 바로 콘솔경고는 사라졌다.
하지만 나는 이전까지 thead와 tbody를 쓰지 않고 table를 사용했었다. 실제로 프로그래머의 초등학교인 w3schools에서도 thead와 tbody 태그를 쓰지 않는다. (변명해보자면 이 학교 출신인 나도 thead, tbody를 안쓴다..)
그래서 이유가 궁금해졌다. 사용안해도 됬기에 안썼는데 하필 react에서만 필요한 이유가 무엇인지!
결과부터 말하자면 내가 그동안 썼던 방식(thead, tbody를 안쓰는)이 브라우저 형님들의 배려라는 것을 알게되었다.
여기 cody 형님의 답변을 보자.
간단히 해석해보자면
브라우저는 tbody 태그가 필요하다. 없으면 자동으로 삽입해준다. 그래서 react의 경우 처음에는 정상으로 동작하지만 다음 rendering할때는 해당 태그들이 없기에 오류가 발생할 여지가 있다. 그래서 warning 해준다.
이 부분을 내 나름의 방식으로 분석해보자면 다음과 같은 말인거같다.
- 맨 처음 rendering 할때는 해당 태그가 없는 상태로 rendering 한다. 그러면 브라우저는 DOM을 정상적으로 그리기 위해 누락된 태그(thead, tbody,tfoot)를 자동으로 만들어서 넣어준다. (정상동작, 에러가능성 없음)
- 변화로 인해 re rendering 될 때 DOM에는 thead 태그가 있는데 리액트의 Virtual DOM에는 해당 태그들이 없다.
- Virtual DOM과 DOM를 비교하며 달라진 부분만 rendering해야하는데 브라우저가 자동으로 만드는 태그들과 리액트가 만든 tag들이 계속 다르다. (정상동작, 에러가능성 생김)
- 따라서 의도한 결과대로 동작시키기 위해 react의 Virtual DOM에도 브라우저의 DOM과 같도록 thead, tbody 태그를 미리 넣어 선언하자
번외로 어떤 형님께서는 일반적으로 html에서도 문제없이 동작하고 브라우저가 자동으로 생산해주는 코드를
UI 라이브러리에 불과한 리액트에서 warning을 때리는건 선넘는 것이라고 말하셨다. 즉 react의 설계오류라는 것이다.
하지만 오픈소스를 가져다 쓰는 개발자에 소개발자에 불과한 너는 "react형님들의 권고니깐 따르라. 싫으면 가서 바꿔"가 결론이셨다. 그러니 우린 thead와 tbody 태그를 꼼꼼히 넣어주자. react 형님들 화나신다.
<table>
<thead>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
<td>$100</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Sum</td>
<td>$180</td>
</tr>
</tfoot>
</table>
꼭 thead, tbody 태그를 넣도록 하자!!