For details, refer to the official JSX specification
Although JSX is a class XML syntax that extends to ECMAScript, it does not itself define any semantics. This means that it is not within the ECMAScript standard range itself. It will not be executed directly by the engine or the browser. It is common to use a compiler preprocessor to convert these jsx into standard ECMAScript.
Spit Groove: Although the starting point of JSX is good, and it is very simple to write, but in the JS to write HTML-like content, my heart is repulsive, feel very unaccustomed. This is not my familiar web development Ah! There is a feeling of developing the app, a custom component.
Want to see how he compiled JSX, so I read the next use JS writing components, the Main method isReact.createElement:
React.createElement(
Type,
[props],
[...children]
)
The first parameter type is type, which is the name, such as h1, div, custom component name, etc.~
The second parameter [props] is actually a variety of properties, how do we write properties in JS, how to write here. For example, img.src="", div.className="", then the attribute is written like {className:"", src:""}, the attribute name is consistent with JS.
The third parameter, in fact, is to extend the child nodes of the current node indefinitely. How many of them do you want?
Take a look at the conversion of the official document, this is the JSX I used to escape with React.createElement, so a set of writing, when is the head. The strong desire for survival made me give up the JS writing and switch to JSX:
Compared to this infinitely nested way of writing, JSX is too friendly. From a semantic point of view, the readability of JSX is also very good. (Forcing yourself to learn JSX forcibly find reasons.)
Learn more about JSX objects
As mentioned in the previous section,
Let element=<h1 className="aaa">A burst</h1>
//Equivalent to
Let element=React.createElement(
"h1",
{className:"aaa"},
"A burst"
)
So is it possible that I directly let let {type,props,children}=element get h1, {className:"aaa"} and A burst? I am still too naive. Type is indeed h1, but props is {className: "aaa", children: "A burst". Huh? How is the children mixed here, then the children are behind? No doubt undefined. That is to say, the structure of a React.createElement or JSX object is like this:
{
Type:"h1",
Props:{
className: "aaa",
Children: "A burst"
}
}
JSX fancy writing (with error demonstration)
JSX has a lot of Chinese writing methods. I am dazzled by the analysis. It is better to analyze and analyze the mysteries of these writings. Why do you want to write this way, and then find a way you like to write. Here I will use let element=XXX as an example, and then you can directly render ReactDOM.render(element, document.getElementById('root'));
Written one: a label embedded with plain text
I used to write these tags in a string when I wrote JS, and then stitched them together. Seeing this writing, I really think it is a bug, the browser will definitely report an error! However, in react, there is no error, which is correct.
Let element=<h1 className="aaa">A burst</h1>
ReactDOM.render(element, document.getElementById('root'));
Wrong writing demo: unlabeled plain text
If it is pure text? Gorgeously reported the wrong. JSX still needs a label package.
Let element=A exploded
Written 2: a tag nested tag mixed text
Then we add a few more sub-elements, it is OK, nothing wrong.
Let element=<h1 className="aaa">aaa<span>A exploded</span>bbbb</h1>
Write three: Fragment package all! Wrong way to demonstrate: multiple tags juxtaposed
If there are many parallel sibling nodes? Suddenly excited! Reported wrong ~ really can't be skinned. why? Everyone is a regular HTML tag.
Let element=
<h1 className="aaa">A exploded</h1>
<h1 className="aaa">A burst</h1>
The official explanation is that it must be wrapped in a closed label. Does it mean that N closed labels can not be juxtaposed?
Let element=
<div>
<h1 className="aaa">A exploded</h1>
<h1 className="aaa">A burst</h1>
</div>
Add a layer of div to the outside. However, there may be more than one unwanted div, and our clean HTML will become a nested hell. The official desire to survive is also very strong, I have already thought of this, so there is an official component called Fragment. It is designed to wrap these elements that don't require a layer of div. The usage of this component:
/ / Do not forget to import, or directly React.Fragment is also possible
Import React,{Fragment} from 'react';
//then
Let element=
<Fragment>
<h1 className="aaa">A exploded</h1>
<h1 className="aaa">A burst</h1>
</Fragment>
I mentioned the structure of element printing: {type:"h1",props:{className:"aaa",children:"A burst"}}, curiosity, I printed the element of <Fragment> of. The result is as follows, type:Symbol(react.fragment), although this root node is a special tag, not a div, p such a normal HTML tag, but also a node. That is to say, element is equivalent to a root node, this root node can only have one, and then this root node can have a myriad of child nodes.
{
Type:Symbol(react.fragment),
Props:{
Children:[
{type: "h1", props: {...}}
{type: "h1", props: {...}}
]
}
Writing method four: Is the array really not working?
I am so curious, I don't want to succumb to all the outside to add a label package, the document says a closed label, so [] can wrap an array like this? Wow~ no error! That is to say, closing a label does not necessarily mean that <></> or [], to represent a whole.
Let element=
[
<li>1</li>,
<li>1</li>,
<li>1</li>
]
Writing 5: Long, good-looking
I also saw a way of writing the entire node by adding () to the outermost layer. I thought at the beginning what this is, it will make the element different. So, I did an experiment and compared two identical nodes. The difference is that the first one has no (), the second one has (), and then the result is true, which means that they are essentially different. So little friends, don't write () will not give an error.
Let element=<div><h1 className="aaa">A burst</h1><h1 className="aaa">A burst</h1></div>
Let element1=(<div><h1 className="aaa">A burst</h1><h1 className="aaa">A burst</h1></div>)
Console.log(JSON.stringify(element1)===JSON.stringify(element))
So what is the use of this bracket? Of course! good looking! Let's look at the same render in the Component if there is no ().
Render() {
Return (
<div className="App">
<p className="App-intro">To get started, edit<code>src/App.js</code> and save to reload.</p>
</div>
)
}
Originally there is (), and then you can wrap the line and align the nodes. It is very comfortable to watch. Then what happens when we go to ()? Neatly neat, but will give you an error!
Render() {
Return
<div className="App">
.....
}
There is a little knowledge here, the content of the return in the js language design must be completed in one line, do not follow the carriage return, or it will report an error. (It's a wayward operation) That means there is no problem writing like this. But I can't guarantee a neat label! This typesetting is ugly. So this time () shows his charm, represents a whole, tells return that I am not over yet. So everyone should not be confused by (), don't be afraid of him.
Render() {
Return <div className="App">
.....
}
Tag attributes in JSX
Writing JSX will reveal that although I am writing HTML, some of the properties are so weird, often wrong, such as the most common className. I summed up a bit of HTML when we write tags, and JS thinking when writing attributes. This is not complicated, it is not difficult to remember!
How to take the class attribute in \\JS?
document.getElementById('myid').className
\\ encountered a special <label id="label" for="xxx"></label>, how to get this for in JS?
document.getElementById('label').htmlFor
Then the question comes, there is a property called style, what do you want to do? Style is more complicated, he is not a value for a string can get it done. Let me first try on the edge of the error.
Trial one: string!
Let element=<div style="color:green">A burst</div>
Wrong! Wrong! The official prompts us that Thestyleprop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX. That is, the style needs to be mapped from the style attribute to his value. , the string is not possible. So you need {marginRight: spacing + 'em'} an object like this. Then why add a layer of {}?
Tentative 2: Single layer{}
Let element=<div style={color:"green"}>A burst</div>
Direct compilation error. In other words, JSX cannot directly contain JS functions. Instead, wrap the JS function with {}. So there is a double layer {}. The first layer is that I am JS, and the second layer is actually the property object itself. You don't have to try the bottom line anymore:
Let element=<div style={{color:"green"}}>A burst</div>
What if I want to add comments to JSX? Direct <!--XXX--> definitely give an error. We can comment in the way of {/*XXX*/}, because the {} tag is a js function, we use the JS comment to pull it! (In fact, JSX is still JS.)
JS in JSX
The above mentioned {} contains JS, then can we play more tricks? Because in {} we can use JS to do whatever we want!
Such as looping (correct):
Let arr=[1,2,3]
Let element=(
{arr.map((v,i)=>
<div>{v}-A explosion</div>
)}
)
If you don't want to loop directly return, you can do this by adding braces inside and then continue to write additional operations. Don't forget to return, only the => function can save the return
Let arr=[1,2,3]
Let element=(
<Fragment>
{arr.map((v,i)=>{
If(v===1){
Return <span>A exploded</span>
}else{
Return <span>B exploded</span>
}
})}
</Fragment>
)
But if JS is outside the tag <></>, it can be used directly without adding {}:
Let element
=
Arr.map((v,i)=>{
If(v==1){
Return <div>{v}-A explosion</div>
}else{
Return <div>{v}-B explosion</div>
}
})
Everyone noticed that element is an object anyway, so the value given to him can only be an object. Therefore, it is not possible to directly operate if/else. It is recommended to operate the outer layer of JSX instead of directly working on the outer layer of JSX.
For example, you can only wait for a red card.
Let element=(
If(v===1){
Return <span>A exploded</span>
}else{
Return <span>B exploded</span>
}
)
It is best to do this:
Let v=1;
Let element;
If(v===1)
Element=<span>A exploded</span>
}else{
Element=<span>B exploded</span>
}
In Comopent's render, we can write this:
Render() {
If(v===1){
Return <span>A exploded</span>
}else{
Return <span>B exploded</span>
}
}
After the study, I found that JSX is JS, and every time I write an element with JSX "syntax", I have to return an array or an object. Just keep this in mind and you can play JSX.