Why do React elements have $$ typeof property?

3r33333. You might think that you are writing jsx: 3r3304. 3r33232.  3r33333.

hi
3r3303.
3r33232.  3r33333. 3r33333. But actually, you call the function:
3r33232.  3r33333.
React.createElement (
/* Type * /'marquee',
/* Props * /{bgcolor: '# ffa7c4'},
/* Children * /'hi' 3rr3311.)

3r33232.  3r33333. 3r33333. And this function returns the object to you. We call this object React element. He tells React what to do next. Your components return a tree of them. 3r3304.
3r33232.  3r33333.
{
type: 'marquee',
props: {
bgcolor: '# ffa7c4',
children: 'hi',
},
key: null,
ref: null,
$$ typeof: Symbol.for ('react.element'), 3r3333311.}

3r33232.  3r33333. 3r33333. If you used React before, you may be familiar with the type, props, key and ref fields. 3r3184. But what is 3r3302. $$ typeof
? And why does he have the symbol as a value? Symbol () 3r3303. ? 3r3187. 3r3304. 3r33232.  3r33333. 3r33333. This is another of those things that you do not need to know in order to use React, but their understanding will give confidence. This article also has some safety tips that you may want to know. Maybe one day you will write your own user interface library, and all this will come in handy. I hope so. 3r3304. 3r33232.  3r33333. 3r33232.  3r33333. 3r33333. Before client libraries of the user interface became common and added basic protection, it was customary in the application code to create HTML and insert it into the DOM: 3r3304. 3r33232.  3r33333.
    const messageEl = document.getElementById ('message'); 3r33333. messageEl.innerHTML = '3r3333301. '+ message.text +'    '; 3r3303.  
3r33232.  3r33333. 3r33333. This works fine, except when your 3r3-3302. message.text has a value of 3r3302. Why do React elements have $$ typeof property? 3r3303. . 3r3184. You do not want everything that strangers wrote displayed verbatim in HTML. 3r3187. 3r3304. 3r33232.  3r33333. 3r33333. Fun fact: if you are rendering only on the client side, injection of the
tag.  3r33333. 3r3304. 3r33333. To protect against such attacks, you can use secure APIs, such as 3r3302. document.createTextNode () or 3r3302. textContent that deal only with text. You can also “shield” the input data by replacing potentially dangerous characters, such as 3r3302. 3r3102. , 3r3302. > and others, in any user-submitted text. 3r3304. 3r33232.  3r33333. 3r33333. However, the cost of the error is high and it is difficult to notice each time when you interpolate a user-recorded string into your output. That is why modern libraries such as React screen text content for strings by default: 3r33232.  3r33333.
    3r33333. 3r33333. {message.text}
3r3304. 3r3303.
3r33232.  3r33333. 3r33333. If message.text - this is a malicious string with the tag 3r3-33132. 3r3303. , or another tag, it will not turn into a real 3r3302 tag. 3r3-33132. 3r3303. . React escapes the contents and then adds it to the DOM. Therefore, instead of seeing the tag. 3r3-33132. 3r3303. , you just see its markup. 3r3304. 3r33232.  3r33333. 3r33333. To display arbitrary HTML inside a React element, you need to write dangerouslySetInnerHTML = {{__html: message.text}} . 3r3184. Record inconveniently read intentionally. 3r3187. Due to its awkwardness, it becomes more noticeable so that you pay attention to it when checking the code. 3r3304. 3r33232.  3r33333. 3r33232.  3r33333. 3r33333. 3r3184. 3r3185. Does this mean that React is completely safe from injection attacks? Not. 3r3186. 3r3187. HTML and DOM offer many attack features that are too complex or slow for React or other user interface libraries. Most of the other attack vectors use attributes. For example, if you write 3r3154. 3r3303. , then beware as the expected link of the following code 3r3302. 'jаvascript: stealYourPassword ()' . Destructuring of user information objects, for example, 3r3302.
3r3303. , is rare, but also dangerous. 3r3304. 3r33232.  3r33333. 3r33333. React can provide protection, but in many cases, vulnerabilities are the consequences of server-side problems, which in any case need to be fixed. 3r3304. 3r33232.  3r33333. 3r33333. However, avoiding custom text content is a sensible first line of defense that captures many potential attacks. Isn't it nice to know that such code is safe? 3r3304. 3r33232.  3r33333.
    //Automatic shielding
3r33333. 3r33333. {message.text}
3r3304. 3r3303.
3r33232.  3r33333. 3r33333. 3r3184. 3r3185. Well, this is not always the case either. 3r3186. 3r3187. And that's where 3r3302. $$ typeof is required. 3r3304. 3r33232.  3r33333. 3r33232.  3r33333. 3r33333. React elements are simple objects: 3r33232.  3r33333.
    {
type: 'marquee',
props: {
bgcolor: '# ffa7c4',
children: 'hi',
},
key: null,
ref: null,
$$ typeof: Symbol.for ('react.element'), 3r3333311.}
3r33232.  3r33333. 3r33333. Although usually you create them using 3r3302. React.createElement () , it's not obligatory. There are valid uses for React to support simple element objects written as I just did above. Of course, you probably don’t want to write them like this, but this can be useful for optimizing compilers, passing user interface elements between workers, or for separating JSX from React code. 3r3304. 3r33232.  3r33333. 3r33333. However, if the server has a potential vulnerability, for example, allowing the user to store an arbitrary JSON object, while the client code expects a string: 3r3304. 3r33232.  3r33333.
    let expectedTextButGotJSON = {
type: 'div',
props: {
dangerouslySetInnerHTML: {3r3333311. __html: '/* write malicious code here * /'
},
},
//3r3311.}; 3r33333. let message = {text: expectedTextButGotJSON}; 3r33333. 3r33333. //The dangerous moment for React ???r3r3311. 3r33333. 3r33333. {message.text}
3r3304. 3r3303.
3r33232.  3r33333. 3r33333. In this case, React ??? will be vulnerable to XSS attacks. To clarify, again, this attack depends on an existing potential server vulnerability. However, React could better protect people from such scenarios. And starting with React 0.1? it is. 3r3304. 3r33232.  3r33333. 3r33333. Starting with React 0.1? each element is marked with a React symbol: 3r33232.  3r33333.
    {
type: 'marquee',
props: {
bgcolor: '# ffa7c4',
children: 'hi',
},
key: null,
ref: null,
$$ typeof: Symbol.for ('react.element'), 3r3333311.}
3r33232.  3r33333. 3r33333. This works because you can't just put characters in JSON. Therefore, even if the server has a potential vulnerability and returns JSON instead of text, JSON cannot contain 3r3302. Symbol.for ('response.element') . React checks the item for 3r3302. element. $$ typeof and refuses to process the item if it is missing or invalid. 3r3304. 3r33232.  3r33333. 3r33333. The most pleasant thing to use is 3r3302. Symbol.for () is that the characters are global between environments such as iframe and workers. Thus, this fix does not prevent the transfer of trusted items between different parts of the application, even under more exotic conditions. Likewise, even if there are multiple copies of React on the page, they can still “agree” with the real value of 3r3302. $$ typeof . 3r3304. 3r33232.  3r33333. 3r33232.  3r33333. 3r33333. What about browsers that do not support symbols? 3r3304. 3r33232.  3r33333. 3r33333. Alas, they do not get this extra protection. React still includes $$ typeof for the element for consistency, but it is set to number - 3r3302. 0xeac7 . 3r3304. 3r33232.  3r33333. 3r33333. Why this particular number 3r3302. 0xeac7 ? Because it looks like "React". 3r3304. 3r33312. 3r33333. 3r33333. 3r33333. 3r3309. ! function (e) {function t (t, n) {if (! (n in e)) {for (var r, a = e.document, i = a.scripts, o = i.length; o-- ;) if (-1! == i[o].src.indexOf (t)) {r = i[o]; break} if (! r) {r = a.createElement ("script"), r.type = "text /jаvascript", r.async =! ? r.defer =! ? r.src = t, r.charset = "UTF-8"; var d = function () {var e = a.getElementsByTagName ("script")[0]; e.parentNode.insertBefore (r, e)}; "[object Opera]" == e.opera? a.addEventListener? a.addEventListener ("DOMContentLoaded", d,! 1): e.attachEvent ("onload", d ): d ()}}} t ("//mediator.mail.ru/script/2820404/"""_mediator") () ();
3r33333. 3r33312.
+ 0 -

Add comment