Tìm hiểu về $$typeof Property trong React

<marquee bgcolor="#000">Chào buổi sáng</marquee> React.createElement(/* type */'marquee',/* props */{ bgcolor:'#000'},/* children */'Hi') Bạn thấy 2 đoạn code trên có liên quan tí nào không ? Thực tế thì có đó, đoạn code đầu tiên sẽ được babel biên dịch ra giống như đoạn code thứ 2. Và function trên sẽ trả về cho chúng ta

<marquee bgcolor="#000">Chào buổi sáng</marquee>
React.createElement(/* type */'marquee',/* props */{ bgcolor:'#000'},/* children */'Hi')

Bạn thấy 2 đoạn code trên có liên quan tí nào không ?
Thực tế thì có đó, đoạn code đầu tiên sẽ được babel biên dịch ra giống như đoạn code thứ 2. Và function trên sẽ trả về cho chúng ta một object, và nó được gọi là React element, nó cho biết tiếp theo React sẽ cần làm gì

{
    type:'marquee',
    props:{
        bgcolor:'#000',
        children:'Hi',},
    key:null,
    ref:null,
    $$typeof: Symbol.for('react.element'),// 🧐}

Mọi thứ trông rất bình thường, nhưng có một thứ mà ta cần phải đặt dấu chấm hỏi ở đây, $$typeof là cái gì và tại sao lại có kiểu Symbol ?
Tò mò thì mình tìm hiểu về nó thôi, thực tế thì nếu chỉ sử dụng React thì nó cũng không ảnh hưởng tới việc coding của chúng ta.
Lúc còn là newbie mình thường sử dụng như thế này để chèn HTML bằng javascript.

const messageEl = document.getElementById('message');
messageEl.innerHTML ='<p>'+ message.text +'</p>';

Sau này khi đi thực tập, mình mới biết làm điều này nguy hiểm tới chừng nào. Thử thay thế tạm đoạn code này vào message.text

  // Thậm chí viblo còn không cho phép mình viết trực tiếp :))
  <imgsrcnerror=" stealYourPassword() ">

Bumpppp, bạn có nguy cơ bị XSS. Một anh senior đã hướng dẫn mình sử dụng tránh bị XSS đó là:

  • Sử dụng document.createTextNode()
  • Sử dụng textContent
  • Bỏ hết ký tự <> đi
    Với React thì mọi thử đơn giản đã là mặc định.
<div>{message.text}</div>

Hoặc có thể sử dụng cách như thế này.

dangerouslySetInnerHTML={{ __html: message.text }}

Nhưng mà tới đây vẫn chưa đủ, vẫn còn rất nhiều cách để XSS bằng HTMLDOM
Ví dụ: <a href={user.website}> hay <div {...userData}> cũng nguy hiểm
Với cách viết này

<div>{message.text}</div>

vẫn chưa đủ an toàn một số trường hợp, một React element được khởi tạo bằng React.createElement() có dạng object như thế này

{
  type:'marquee',
  props:{
    bgcolor:'#ffa7c4',
    children:'hi',},
  key:null,
  ref:null,
  $$typeof: Symbol.for('react.element'),}

Nếu chúng ta lưu trữ nó ở trên server như một JSON, với React 0.13 đây là điểm bị lợi dụng để XSS

// JSON được lưu trên serverlet expectedTextButGotJSON ={
  type:'div',
  props:{
    dangerouslySetInnerHTML:{
      __html:'/* đưa đoạn XSS vào đây */'},},// ...};let message ={ text: expectedTextButGotJSON };// Nguy hiểm<p>{message.text}</p>

Phiên bản 0.14 React hỗ trợ xử lý con bug này bằng cách thêm đánh dấu đây chính hiệu là React element bằng Symbol

{
  type:'marquee',
  props:{
    bgcolor:'#ffa7c4',
    children:'hi',},
  key:null,
  ref:null,
  $$typeof: Symbol.for('react.element'),}

Tại vì, trong JSON chúng ta không thể chèn một Symbol (khi stringyfy Symbol sẽ trở thành undefined), thậm chí Back end có cho phép return JSON thay vì text thì cũng không thể đưa Symbol.for('react.element') vào trong JSON đó.

Điều tuyệt vời nữa, là Symbol.for() thì scope ở mức global giữa các môi trường như iframe, worker. Nghĩa là sử dụng component qua lại giữa các môi trường khác nhau cũng không bị ảnh hưởng.

Nhưng có một điều, trình duyệt không hỗ trợ Symbol thì sao?
React sẽ vẫn thêm vào property$$typeof, nhưng với giá trị 0xeac7, tại sao là 0xeac7? Tại React team thấy nhìn nó giống chữ "React" =))

Nguồn: viblo.asia

Bài viết liên quan

Thay đổi Package Name của Android Studio dể dàng với plugin APR

Nếu bạn đang gặp khó khăn hoặc bế tắc trong việc thay đổi package name trong And

Lỗi không Update Meta_Value Khi thay thế hình ảnh cũ bằng hình ảnh mới trong WordPress

Mã dưới đây hoạt động tốt có 1 lỗi không update được postmeta ” meta_key=

Bài 1 – React Native DevOps các khái niệm và các cài đặt căn bản

Hướng dẫn setup jenkins agent để bắt đầu build mobile bằng jenkins cho devloper an t

Chuyển đổi từ monolith sang microservices qua ví dụ

1. Why microservices? Microservices là kiến trúc hệ thống phần mềm hướng dịch vụ,