2016-05-20 16 views
53

Có sự khác biệt "đằng sau hậu trường" nào khi thiết lập innerHTML của phần tử so với cài đặt thuộc tính dangerouslySetInnerHTML trên một phần tử không? Giả sử tôi đang khử trùng đúng cách vì mục đích đơn giản.React.js: Đặt bên trongHTML vs dangerouslySetInnerHTML

Ví dụ:

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> 
    ); 
    } 
}); 

tôi đang làm một cái gì đó nhiều hơn một chút phức tạp hơn so với ví dụ trên, nhưng ý tưởng chung là như nhau

Trả lời

97

Có sự khác biệt!

Hiệu ứng tức thì khi sử dụng innerHTML so với dangerouslySetInnerHTML giống hệt nhau - nút DOM sẽ cập nhật với HTML được chèn.

Tuy nhiên, đằng sau hậu trường khi bạn sử dụng dangerouslySetInnerHTML nó cho phép Phản ứng biết rằng HTML bên trong thành phần đó không phải là thứ mà họ quan tâm.

Vì React sử dụng một DOM ảo, khi nó đi để so sánh khác với DOM thực tế, nó có thể thẳng lên bỏ qua kiểm tra con của nút đó vì nó biết HTML đến từ một nguồn khác. Vì vậy, có hiệu suất đạt được.

Quan trọng hơn là, nếu bạn chỉ cần sử dụng innerHTML, React không có cách nào để biết nút DOM đã được sửa đổi. Lần sau, chức năng render được gọi là, Phản ứng sẽ ghi đè nội dung đã được chèn thủ công theo ý kiến ​​của trạng thái chính xác của nút DOM đó.

Giải pháp của bạn để sử dụng componentDidUpdate để luôn đảm bảo nội dung được đồng bộ hóa Tôi tin rằng sẽ hoạt động nhưng có thể có flash trong mỗi lần hiển thị.

+6

Tôi đã viết một bài kiểm tra nhỏ, phi khoa học để hiển thị sự khác biệt giữa việc chèn một SVG và sử dụng 'dangerouslySetInnerHTML': https://www.webpackbin.com/bins/-KepHa-AMxQgGxOUnAac - điều chỉnh phương thức innerHTML là nhanh gấp hai lần (xem bảng điều khiển trong webpackbin) – Joscha

+0

Đó là sự thật và dễ dự đoán. Vì innerHTML là một phương thức gốc liên kết mã SVG trực tiếp với DOM mà không xem xét bất cứ điều gì. Mặt khác, dangerouslySetInnerHTML là phương thức đến từ React rằng mã SVG phải được phân tích cú pháp như các thành phần React Children trước khi đưa chúng vào DOM ảo và sau đó đưa vào DOM. – Up209d

Các vấn đề liên quan