안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
# 상황
- React 18
- ChatGPT 채팅 웹사이트
Naver Whale에서 영어 → 한국어 자동 번역 기능을 키고
영어로 대화가 이루어진 A 채팅방 → B 채팅방 → A 채팅방 내용을 클릭 시 아래와 같은 오류가 발생했다.
🐛 오류 메세지
Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
💡 해결방안
채팅 메세지를 보여줄 때 react-markdown
패키지를 이용하였고, p 태그인 경우 아래와 같이 p 태그로 감싸 리턴해주었다.
p({ children }) {
useEffect(() => {
setIsCodeWriting(false);
}, []);
return (
<p>{children}</p>
);
},
아래와 같이 TextNode를 span 태그로 감싸주어 해결해주었다.
p({ children }) {
useEffect(() => {
setIsCodeWriting(false);
}, []);
// 기존에는 <p>{children}</p>로 메세지를 찍어주었는데, 이 경우 네이버웨일에서 자동번역을 켜고 번역할 내용이 있는 A 채팅방 -> B 채팅방 -> 다시 A 채팅방에 들어가면
// Failed to execute 'removeChild' on 'Node' 오류가 발생하면서 흰 화면으로 아예 먹통이 됨
// google translate가 작동하는 방식이 Element 내에 TextNode를 찾아서 font 태그로 변경해버리고 기존 TextNode는 없애버리는데, 다시 A 채팅방에서 이미 삭제해버린 TextNode를 찾아 removeChild를 하려고 하니까 발생하는 오류.
// 따라서 TextNode를 span 태그로 감싸주어 React가 참조하는 Node가 font 태그로 대체되어도 DOM 트리에 남게해줘야 한다고 함(그래서 Element 내에 TextNode를 또 span으로 감싸주어 아래처럼 p 태그 내에 span 태그가 있음)
// 참고사이트: https://github.com/facebook/react/issues/11538#issuecomment-390386520, https://martijnhols.nl/gists/everything-about-google-translate-crashing-react
return (
<p>
<span>{children}</span>
</p>
);
},
🔥 원인
구글 자동 번역이 어떤 방식으로 작동하는지 먼저 파악할 필요가 있다.
[구글 자동 번역 작동 방식]
- TextNode를 찾는다
- 찾은 TextNode를 번역될 문장을 포함한 FontElement 로 대체한다.
예를 들어, <p>Hello</p>
가 있다고 가정했을 때
- TextNode를 찾는다 TextNode: "Hello"
- 찾은 TextNode를 번역될 문장을 포함한 FontElement 로 대체한다.
<p><font>안녕하세요</font></p>
로 대체
위와 같은 과정을 거쳐서 번역된 문장이 보여지게 된다.
이 때, TextNode는 이미 지워져버렸기 때문에 마운트된 DOM에는 TextNode인 Hello가 없을 것이다.
따라서 이미 번역을 했던 페이지를 다시 로드할 경우, TextNode를 찾아서 remove를 해버리니까 removeChild를 할 수 없어요~ 라는 오류가 발생한다는 것!
이를 방지하기 위해 TextNode를 span 태그로 감싸주어 TextNode를 직접 삭제하지 못하도록 해준다.
span 태그로 감싼 TextNode를 쉽게 찾아주는 eslint-plugin-sayari 를 설치하여 처리해준다면 좀 더 수월할 것이다.
https://github.com/sayari-analytics/eslint-plugin-sayari
근데 정말 아이러니하게도.. Chrome에서는 해당 현상이 발생하지 않는다..😅
참고사이트 (⭐️ 아래 참조한 참고사이트를 정독한다면, 원인 파악 및 흐름을 이해할 수 있을 것이니 꼭! 정독해보길 추천한다.)
https://martijnhols.nl/gists/everything-about-google-translate-crashing-react
https://github.com/facebook/react/issues/11538#issuecomment-390386520