By Qianxing
Before React emerged, there were three important libraries and frameworks in the Frontend.
React is a declarative, efficient, and flexible JavaScript library for building user interfaces. The core idea of React is to combine short, independent code fragments into complex UI interfaces. These code fragments are called components. Compared with the MVC framework, React is more like the V in the MVC framework, which is only responsible for rendering the user interaction view.
React has three disruptive ideas I will introduce in the following chapter:
Use Create React App [1] to initialize a React Web project:
$ npx create-react-app learn-react --template typescript
$ cd learn-react
$ npm start
After the npm start
is executed, the browser opens the project homepage at http://localhost:3000
.
React provides React Developer Tools[2], which is integrated into the Chrome Dev Tools, so you can view the React component tree and its corresponding Props and State.
app.tsx
import React, { useState } from 'react';
function Button(props: { count: number }): JSX.Element {
const [count, setCount] = useState(props.count);
return (
<button
onClick={() => {
setCount((c) => c + 1);
}}
>
{count}
</button>
);
}
function App() {
const [count, setCount] = useState(0);
return (
<div className="App">
<Button count={5} />
</div>
);
}
export default App;
index.tsx
import React from 'react';
import * as ReactDOMClient from 'react-dom/client';
import App from './app';
const rootElement = document.querySelector('body') as Element;
const root = ReactDOMClient.createRoot(rootElement);
root.render(<App />);
Open the Chrome Dev Tools, and the Components
tab has been added:
Next, let's do a Todo project to experience React:
Before you start writing React programs, you need to understand JSX. JSX is React's syntax extension to JavaScript, which is used to express the view and interaction logic of the page through the HTML-like markup
within the JavaScript file.
<div className="container">
<CustomComponent
onClick={() => {alert('Hello')}}
>
Hello {props.name}!
</CustomComponent>
</div>
Web pages are composed of HTML content, CSS styles, and JavaScript interactions. For a long time, web developers have separated the three into independent files, which are separated according to technology.
The traditional page content is mainly defined by HTML, and JavaScript logic is embellishment. As modern web page interactivity improves, page content is dynamically generated by JavaScript logic to a large extent. At the same time, rendering logic is intrinsically coupled with other UI logic (such as binding processing events in UI), notifying the UI when the state changes at a certain time and displaying prepared data in UI.
React uses JSX to integrate rendering logic with HTML markup.
This way, developers shift their focus from technical implementations (such as HTML templates and JavaScript rendering logic) to page functional units (such as Sidebar and Form).
Functions that return JSX are React's simplest components and can be nested (like HTML markup). React uses the props
parameters to pass data to components to improve the reusability of components.
/**
* The JSX syntax implicitly calls React.createElement.
* So, although there is no statement to call React in the code, you still need to introduce it.
*/
import React from 'react';
interface IButton {
/** Click the button to show copy */
text: string;
/** Click the button to jump to the link */
link?: string;
/** Click the button to customize the event */
onClick?: (event?: Event) => void
}
function Button(props: IButton) {
const { text, link, onClick } = props;
const redirectHandler = () => {
location.href = link;
};
return (
<div
className="button"
onClick={onClick | redirectHandler}
>
{text}
</div>
);
}
export default Button;
When a component is used, it is assembled into a props object through the attributes of its tag and passed to the component. The syntax is similar to the HTML attribute, but the value can be any JavaScript object.
import React from 'react';
/**
* Import the default content of the export in the./button.tsx file and name it Button.
* The .tsx extension name can be omitted.
*/
import Button from './button';
interface IDialog {
title: string;
content: Element;
showClose: boolean;
}
function Dialog(props: IDialog) {
const { title, content, showClose = false, children } = props;
const hideDialog = () => {
// ...
}
return (
<div>
<div className="dialog-title"> {title} </div>
<div className="dialog-body"> {content | children} </div>
{/* The attributes defined by Button props are exposed through the tag attribute */}
<Button
title="Cancel"
onClick={hideDialog}
/>
<Button
title="Confirm"
onClick={() => { }}
/>
</div>
);
}
export default Dialog;
After the component is written, the component is rendered to the page through the react-dom [3].
import React from 'react';
import ReactDOM from 'react-dom/client';
import Dialog from './dialog';
// Render the component to the element whose page id is root.
const rootElement = document.getElementById('root');
const root = ReactDOM.createRoot(rootElement);
root.render(
<Dialog
title="demo dialog"
content="this is a dialog"
showClose={false}
/>
);
React components have several conventions:
props
to expose the component's configurable attributes, and its children components are injected by React through the children's
attribute.Like the simple demos written above, JSX must have a root node. Even if multiple sibling elements have no parent nodes, they need to be wrapped with a virtual node <></>
.
{/* Illegal JSX */}
<div id="box1"></div>
<div id="box2"></div>
{/* Legal JSX */}
<>
<div id="box1"></div>
<div id="box2"></div>
</>
Markup doesn't necessarily need to be closed in HTML.
<meta charset="UTF-8">
<br>
<img src="https://g.alicdn.com/logo.png">
HTML native markup can be mixed in JSX, but all markup must be closed.
<>
<meta charset="UTF-8" />
<br/>
<img src="https://g.alicdn.com/logo.png"/>
</>
HTML attribute name | JSX attribute name |
class | className |
for | htmlFor |
function HelloWorldComponent(props) {
const divStyle = {
// You can easily set dynamic styles.
backgroundImage: 'url(' + props.imgUrl + ')',
// However, the static style should try to set the class through className and solve it through css file.
// Static styles like color: 'blue' are not recommended to be written directly in JSX.
color: 'blue',
};
return (
<div style={divStyle}>
Hello World!
</div>
);
}
defaultValue
attribute for Form form, sets default values, and uses the HTML-consistent value
attribute at runtime.JSX escapes text that is set directly to prevent XSS attacks.
const content = `
A picture should be shown here<br>
<img src="https://sc02.alicdn.com/kf/HTB1gUuPUkzoK1RjSZFl761i4VXaw.png" />
`;
<div>
{content}
</div>
Page effect:
When security is guaranteed, you can disable the escape effect through dangerouslySetInnerHTML
to display raw HTML.
const content = `
A picture should be shown here<br>
<img src="https://sc02.alicdn.com/kf/HTB1gUuPUkzoK1RjSZFl761i4VXaw.png" />
`;
<div dangerouslySetInnerHTML={{ __html: content }}/>
In JSX, you can use {}
to wrap JavaScript expressions to handle dynamic logic (such as attribute value and child elements). The most common usage is:
{variable name}
reads the variable value. The double-layer {{}} is not a special syntax. It is a shortcut to {object}
.<div style={{ color: 'red' }}></div>
// Equivalent to
const styleObj = { color: 'red' };
<div style={styleObj}></div>
interface IStuff {
name: string;
sex: 'male' | 'female';
}
function App () {
const list: Array<IStuff> = [
{ name: 'Byron', sex: 'male' },
{ name: 'Casper', sex: 'male' },
{ name: 'Junice', sex: 'female' },
];
return (
<ul className="stuff-list">
{
list.map(stuff => { // Generate multiple
const { name, sex } = stuff;
return (
{
<li
/* The actual programming className setting has a better expression. Here, only the demo ternary expression is used. */}
className={sex === 'male' ? 'stuff-male' : 'stuff-female'}
onClick={() => { alert(name) }}
>
// Read the variable value
{name}
</li>
);
})
}
</ul>
);
}
Annotations in JSX also need to be wrapped in {}
, but this writing is inconvenient. Most compilation tools can handle double slash style //
annotations.
The return value of JSX is neither a DOM element nor an HTML string but a JSON description of the DOM, which is React Element:
<button id="9527" className="btn-primary">
<span style={{ color: 'red' }}>
This is a Button
</span>
</button>
JSX is expressed in such a structure:
{
"type": "button",
"props": {
"id": "9527",
"className": "btn-primary",
"children": [
{
"type": "span",
"props": {
"style": { "color": "red" },
"children": "This is a Button"
}
}
]
}
}
After compilation, it is called like this:
React.createElement("button", {
id: "9527",
className: "btn-primary"
},React.createElement("span", {
style: {
color: 'red'
}
}, "This is a Button"));
React.createElement(type, props, ...children)
, As mentioned above, React automatically injects children into props during this process.
After understanding JSX, you can start writing static React Components.
[1] https://create-react-app.dev/
[2] https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi
Alibaba Clouder - March 2, 2021
Alibaba Clouder - June 23, 2020
Alibaba Clouder - May 27, 2019
Harikrishna - May 24, 2023
HaydenLiu - December 5, 2022
ApsaraDB - November 17, 2022
Explore Web Hosting solutions that can power your personal website or empower your online business.
Learn MoreA low-code development platform to make work easier
Learn MoreExplore how our Web Hosting solutions help small and medium sized companies power their websites and online businesses.
Learn MoreHelp enterprises build high-quality, stable mobile apps
Learn More