[React.js] Tip: string 형태의 html을 렌더링하기, newline(\n) 을 BR 태그로 변환하기


React 매뉴얼의 “Dangerously Set innerHTML” 페이지에 따르면, React에서는 cross-site scripting (XSS) 공격을 막기 위하여, 렌더링 메소드 내부에서 html 태그가 담겨있는 string 형태를 렌더링하면, 태그가 안 먹히고 문자열 그대로 렌더링되게 됩니다:

만약에 저 문자열에 태그가 적용된 상태로 렌더링이 된다면, 사용자가 임의로 웹페이지에 스크립트를 먹일수도있게되서 취약점이 생기겠지요.

React.js 에선 이 취약점을 원천차단하기위하여 그냥 무조건 텍스트형태로만 렌더링하게 설정되었습니다. (물론, 이 취약점은 클라이언트측이나 서버측에서 escape 를 잘해서 보안에 신경을 쓰면 큰 문제는 발생하지 않을것입니다)

만약에 여러분이 “난 문자열을 html 형태로 렌더링하게되면 취약한걸 알고있어. 그리고 여기에 난 대비하고 있으니까 걱정 마!” 라고 생각하신다면, React가 경고했음에도 불구하고, 쌩까고 하는 방법이 있습니다. 바로 ‘dangerouslySetInnerHTML’ 인데요.

사용법은 간단합니다. 아래 코드를 살펴보세요:


한번 이러한 상황에 대하여 생각해봅시다..

우리가 렌더링 해야되는 문자열이, 뭐 특별한 HTML 태그는 필요가 없는데 newline ( <BR/> ) 이 필요 할 경우엔 어떻게 해야할까요?

겨우 여러줄을 렌더링하고싶을 뿐인데 서버측에서 html escape 를 구현하고 dangerouslySetInnerHTML 를 사용 할 필요가 있을까요?

 

우선, 보통 여러줄의 문자열을 JSON 형태로 담을 땐 newline 을 위하여 \n 문자를 사용하죠?

이걸 그대로 렌더링하면.. 새로운 줄이 생기는게 아니라 그냥 space 만 있을 뿐입니다.

그리고 아무생각없이.. JavaScript 의 replace 기능을 사용하여 \n 을 <BR/> 로 변환한다면? 될리가없죠.

이런 상황에서, 윗 부분에서 알려드린  dangerouslySetInnerHTML 를 써도 되겠지만 더 괜찮은 트릭이 있습니다.

React.js 강좌 6-1편에서 다뤘던 컴포넌트 Mapping 을 통하여 이 문제를 아주 쉽게 해결 할 수 있습니다.

        {
          data.split('\n').map( line => {
            return (<span>{line}<br/></span>)
          })
        }

이런식으로, 문자열을 ‘\n’ 으로 split 하면 각 line 이 있는 배열이 생성되겠죠?

그 배열을 사용하여 매핑 기능을 통하여 컴포넌트 배열을 새로 생성후 렌더링하면 해결됩니다.

 

dfbsdbf

  • Jason Park

    좋은 정리네요~ 같은 방법이긴 한데 data.split(‘n’).map(line => {line}) 로 조금 더 간단하게도 가능해요. css 사용하시면 white-space: pre/pre-line/pre-wrap 사용하시면 굳이 line break 안넣으셔도 되구요.

    • 이것도 좋은 방법이네요 ㅎㅎ 감사합니다

  • BaHwan Han

    좋은 팁이네요.