JSX
is a syntax for quickly generating react
elements. It is actually a syntax sugar for React.createElement(component, props, ...children)
. At the same time, JSX
is a syntax extension of Js
, containing all Js
functionalities.
Previously, Facebook
was a big player in PHP
, so the initial inspiration for React
came from PHP
.
In 2004
, everyone was still using string concatenation in PHP
to develop websites.
$str = "<ul>";
foreach ($talks as $talk) {
$str += "<li>" . $talk->name . "</li>";
}
$str += "</ul>";
This way of writing code is not only unappealing but also prone to security issues such as XSS
. The method of dealing with this is to escape any user input, but if the string is escaped multiple times, the number of unescaping must also be the same, otherwise the original content will not be obtained. If HTML tags are accidentally escaped, the HTML tags will be directly displayed to the user, resulting in a poor user experience.
By 2010
, in order to code more efficiently and avoid errors in escaping HTML tags, Facebook
developed XHP
. XHP
is a syntax extension for PHP
that allows developers to use HTML
tags directly in PHP
instead of using strings.
$content = <ul />;
foreach ($talks as $talk) {
$content->appendChild(<li>{$talk->name}</li>);
}
This way, all HTML tags use a syntax different from PHP, making it easy to distinguish which need to be escaped and which do not. Shortly afterward, Facebook
engineers discovered that they could create custom tags, and by combining these custom tags, it was helpful in building large applications.
By 2013
, frontend engineer Jordan Walke
proposed a bold idea to his manager: to migrate the extension features of XHP
to Js
. The primary task was to have an extension that allowed Js
to support XML
syntax, and this extension is called JSX
. Since at the time Node.js
was already well established at Facebook
, the implementation of JSX
was achieved quickly.
const content = (
<TalkList>
{talks.map(talk => <Talk talk={talk} />)}
</TalkList>
);
React
believes that the rendering logic is essentially coupled with other UI
logics, such as the need to bind event handling in the UI
, notify the UI
when the state changes at certain moments, and display prepared data in the UI
.
React
does not advocate for the artificial separation of markup and logic into different files. Instead, it achieves separation of concerns by storing both in loosely coupled units called components.
React
does not force the use of JSX
, but most people find that visually placing JSX
and UI
together in JavaScript
code has an auxiliary effect, and it also allows React
to display more useful errors and warnings.
In simple terms, JSX
can effectively describe the structure of the html
page, make it convenient to write html
code in Js
, and have all the functionalities of Js
.
The advantages of JSX
mainly manifest in the following three points:
- Fast:
JSX
executes faster because it is optimized after being compiled toJavaScript
code. - Secure: Compared to
JavaScript
,JSX
is statically typed and mostly type-safe. When developing withJSX
, the quality of the application will be higher because many errors will be discovered during the compilation process. It also provides compiler-level debugging functionality. - Simple: The syntax is concise and easy to get started with.
JSX
defines some rules and usage:
JSX
can only have one root element.JSX
tags must be closed, and if there is no content, it can be written in a self-closing form such as<div />
.Js
expressions can be embedded inJSX
using{}
.JSX
will be translated bybabel
into a function call ofReact.createElement
, which will create aJs
object describing theHTML
information.- The child element in
JSX
can be a string literal. - The child element in
JSX
can be aJSX
element. - The child element in
JSX
can be a group of elements stored in an array. - The child element in
JSX
can be aJs
expression and can be mixed with other types of child elements, and can be used to display lists of arbitrary lengths. - The child element in
JSX
can be a function and function call. - If the child element in
JSX
isboolean/null/undefined
, it will be ignored. If using the&&
operator, ensure that the preceding value is a boolean. If it is0/1
, it will be rendered. - When defining
React
components in object properties, the dot syntax of theobject
can be used to reference the component. React
elements will be translated into a call to theReact.createElement
function, with the component as a parameter, soReact
and the component must be in scope.React
elements need to start with a capital letter, or assign the element to a variable starting with a capital letter, as lowercase letters will be considered asHTML
tags.- Expressions cannot be used as
React
element types; they need to be assigned to a variable starting with a capital letter and then used as a component.
In the example, we declare a variable called name
and then use it in JSX
, wrapping it in curly braces. In JSX
syntax, you can place any valid JavaScript
expression within the curly braces. For example, 2 + 2
, user.firstName
, or formatName(user)
are all valid JavaScript
expressions.
const name = "Josh Perez";
const element = <h1>Hello, {name}</h1>;
ReactDOM.render(
element,
document.getElementById("root")
);
Similarly, JSX
is also an expression. JSX
is naturally meant to be compiled before use. After compilation, JSX
expressions are transformed into regular JavaScript
function calls, resulting in JavaScript
objects when evaluated. This means that you can use JSX
within if
statements and for
loops, assign JSX
to variables, pass JSX
as parameters, and return JSX
from functions.
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
Typically, you can specify attribute values as string literals using quotes. You can also use curly braces to insert a JavaScript
expression into an attribute value. When embedding a JavaScript
expression in an attribute, do not include quotes outside the curly braces. Because JSX
syntax is closer to JavaScript
than to HTML
, React DOM
uses camelCase
naming convention to define attribute names, as opposed to the naming convention used for HTML
attributes. For example, class
in JSX
becomes className
, and tabindex
becomes tabIndex
.
const element1 = <div tabIndex="0"></div>;
const element2 = <img src={user.avatarUrl}></img>;
In JSX
, you can also use </>
to close tags, and you can directly define many child elements.
const element1 = <img src={user.avatarUrl} />;
const element2 = (
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
</div>
);
You can safely insert user input into JSX
. By default, React DOM
escapes all input before rendering, ensuring that content that is not explicitly written is never injected into your application. All content is converted to strings before rendering, effectively preventing XSS
cross-site scripting attacks.
const title = response.potentiallyMaliciousInput;
// Safe to use directly
const element = <h1>{title}</h1>;
In reality, Babel
transpiles JSX
into a function call named React.createElement()
. Elements defined using React.createElement()
are equivalent to elements generated using JSX
, making JSX
inherently compilable.
const element1 = (
<h1 className="greeting">
Hello, world!
</h1>
);
// Equivalent to
const element2 = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
React.createElement()
carries out preliminary checks to help you write error-free code, but essentially, it creates objects. These objects are called React elements
, which describe the content you want to see on the screen. React
reads these objects, uses them to build the DOM
, and keeps them updated as necessary.
// Note: This is a simplified structure
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};
Actually, this is a node in the virtual DOM
. Virtual DOM
is a programming concept where the UI is kept in an idealized or virtual form in memory, and it is synchronized with the real DOM through libraries like ReactDOM
, in a process called reconciliation. This approach gives React
a declarative API, where you tell React
what state you want the UI to be in, and React
ensures that the DOM matches that state. This liberates you from necessary operations such as attribute manipulation, event handling, and manual DOM updates when building applications.
Rather than considering Virtual DOM
as a technology, it's more of a pattern, and people often express different things when referring to it. In the React
world, the term Virtual DOM
is usually associated with React
elements because they both represent objects of the user interface. React
also uses an internal object called fibers
to store additional information about the component tree, and these two are also considered part of the Virtual DOM
implementation in React
. Virtual DOM
also lays the foundation for using the diff
algorithm.
<div class="root" name="root">
<p>1</p>
<div>11</div>
</div>
// Use JavaScript objects to describe the above node and document
{
type: "tag",
tagName: "div",
attr: {
className: "root",
name: "root"
},
parent: null,
children: [{
type: "tag",
tagName: "p",
attr: {},
parent: {} /* Reference to the parent node */,
children: [{
type: "text",
tagName: "text",
parent: {} /* Reference to the parent node */,
content: "1"
}]
},{
type: "tag",
tagName: "div",
attr: {},
parent: {} /* Reference to the parent node */,
children: [{
type: "text",
tagName: "text",
parent: {} /* Reference to the parent node */,
content: "11"
}]
}]
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>JSX Example</title>
</head>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = { date: new Date() };
}
componentDidMount() {
this.timer = setInterval(() => this.tick(), 1000);
}
componentWillUnmount() {
clearInterval(this.timer);
}
tick() {
this.setState({ date: new Date() });
}
render() {
return (
<div>
<h1>{this.props.tips}</h1>
<h2>Now: {this.state.date.toLocaleTimeString()}</h2>
</div>
);
}
}
class App extends React.Component{
constructor(props){
super(props);
this.state = {
showClock: true,
tips: "Hello World!"
}
}
updateTips() {
this.setState((state, props) => ({
tips: "React update"
}));
}
changeDisplayClock() {
this.setState((state, props) => ({
showClock: !this.state.showClock
}));
}
render() {
return (
<div>
{this.state.showClock && <Clock tips={this.state.tips} />}
<button onClick={() => this.updateTips()}>Update Tips</button>
<button onClick={() => this.changeDisplayClock()}>Change Display</button>
</div>
);
}
}
var vm = ReactDOM.render(
<App />,
document.getElementById("root")
);
https://github.com/WindrunnerMax/EveryDay
https://www.zhihu.com/question/265784392
https://juejin.cn/post/6844904127013584904
https://zh-hans.reactjs.org/docs/introducing-jsx.html