React.js : innerHTML 대 위험한 설정


171

요소의 innerHTML을 설정하는 것과 요소에 dangerouslySetInnerHTML 속성을 설정하는 것과 "장면 뒤에"차이가 있습니까? 간단하게하기 위해 사물을 제대로 소독한다고 가정합니다.

예:

var test = React.createClass({
  render: function(){
    return (
      <div contentEditable='true' dangerouslySetInnerHTML={{ __html: "Hello" }}></div>
    );
  }
});

vs

var test = React.createClass({
  componentDidUpdate: function(prevProp, prevState){
    this.refs.test.innerHTML = "Hello";
  },
  render: function(){
    return (
      <div contentEditable='true' ref='test'></div>
    );
  }
});

위의 예제보다 조금 더 복잡한 작업을 수행하고 있지만 전반적인 아이디어는 동일합니다.

답변:


237

예, 차이가 있습니다!

innerHTMLvs 를 사용하는 즉시 효과 dangerouslySetInnerHTML는 동일합니다. DOM 노드는 삽입 된 HTML로 업데이트됩니다.

그러나 사용 하면 뒤에서dangerouslySetInnerHTML React는 해당 구성 요소 내부의 HTML이 신경 쓰지 않는 것을 알 수 있습니다.

React는 가상 DOM을 사용하기 때문에 diff와 실제 DOM을 비교할 때 HTML이 다른 소스에서 온 것을 알고 있기 때문에 해당 노드의 자식을 검사하지 않고 바로 우회 할 수 있습니다 . 따라서 성능이 향상됩니다.

더 중요한 것은 단순히를 사용 innerHTML하면 React는 DOM 노드가 수정되었음을 알 수있는 방법이 없다는 것입니다. 다음에 render함수가 호출되면 React는 해당 DOM 노드의 올바른 상태로 생각되는 것을 수동으로 주입 한 컨텐츠겹쳐 씁니다 .

componentDidUpdate콘텐츠가 항상 동기화되도록하는 데 사용할 솔루션 은 효과가 있다고 생각하지만 각 렌더링 중에 플래시가있을 수 있습니다.


11
나는 SVG를 인라인 및 사용의 차이 보여주기 위해 작은 비 과학적 반환 한 테스트를 썼다 dangerouslySetInnerHTML: webpackbin.com/bins/-KepHa-AMxQgGxOUnAac - 툰스를 innerHTML을 방법은 빠른 속도로 거의 두 배 밖으로합니다 (webpackbin 콘솔 참조)
Joscha

4
사실이며 예측하기 쉽습니다. innerHTML은 아무 것도 고려하지 않고 SVG 코드를 DOM에 직접 바인딩하는 기본 메소드이므로 한편, dangerouslySetInnerHTML은 SVG 코드를 가상 DOM에 배치 한 다음 DOM에 렌더링하기 전에 SVG 코드를 React Component 하위로 구문 분석해야하는 React의 메소드입니다.
Up209d

3

에 따르면 위험하게 설정 innerHTML을 ,

잘못 사용 innerHTML하면 크로스 사이트 스크립팅 (XSS)을 할 수 있습니다 공격을받을 수 있습니다. 표시를 위해 사용자 입력을 삭제하면 오류가 발생하기 쉬우 며 제대로 삭제하지 않으면 인터넷에서 웹 취약점이 발생하는 주요 원인 중 하나입니다.

우리의 디자인 철학은 물건을 안전하게 만드는 것이 "쉬운"것이어야하고 개발자가 "안전하지 않은"작업을 수행 할 때 그들의 의도를 명시 적으로 명시해야한다는 것입니다. 소품 이름dangerouslySetInnerHTML 은 의도적으로 무섭게 선택되었으며, 소품 값 (문자열 대신 객체)을 사용하여 위생 처리 된 데이터를 나타낼 수 있습니다.

보안 효과를 완전히 이해하고 데이터를 올바르게 삭제 한 후 키 __html와 삭제 된 데이터 만 값으로 포함하는 새 개체를 만듭니다 . 다음은 JSX 구문을 사용하는 예입니다.

function createMarkup() {
    return {
       __html: 'First &middot; Second'    };
 }; 

<div dangerouslySetInnerHTML={createMarkup()} /> 

아래 링크를 사용하여 자세히 알아보십시오.

문서 : DOM 요소-dangerouslySetInnerHTML 반응 .


1
이것은 질문에 대답하지 않습니다.
Quentin

2

( dangerouslySetInnerHTML )을 기반으로 합니다.

원하는 것을 정확하게 수행하는 소품입니다. 그러나 그들은 신중하게 사용해야한다는 것을 전달하기 위해 이름을 지정합니다.


1
문서에 따르면 이것이 여전히 혼란스러운 유일한 이유 인 것 같습니다.
mkb
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.