Contents
In our previous post Initialize React project using Umi, we learned to write a page component
export default () => {
return <div>hello world</div>;
}
After inserting this component on the page, Hello World will be displayed. However, the previous section did not explain the meaning of this code, just let everyone copy it.
This section explains what a component is and how to write it. This is the basis for using React and Ant Design. Only after learning these contents can we understand the following knowledge. If you already know React, you can skip this section.
What are the components?
According to the function division, a web page can be composed of multiple independent functional units. Such functional units are called “components”. For example, a typical web page is divided into three parts: header, content, and footer, which can be written as three components: Header, Content, Footer. These components are assembled to form a page.
Components can also contain the next level of components. For example, the “article” component can contain a “form” component, and the “form” component can also contain a “button” component.
The benefits of components are many, and here are some of them.
- Conducive to refine the UI logic, different components are responsible for different functional points.
- Conducive to code reuse, multiple pages can use the same components.
- Conducive to the division of labor, different engineers are responsible for different components.
The core concept of React is components. The main function of this framework is to define a set of specifications for writing and using components. The code at the beginning of this section defines one of the simplest components.
export default () => {
return <div>hello world</div>;
}
The above code uses the ES6 module format, and an arrow function is the default export. After this function is executed, it returns a piece of JSX code (described later), which represents the hello world block. This is the simplest way to write React components.
JSX syntax
Users who are exposed to React for the first time will have a common question as to why HTML code can be inserted directly into JavaScript code. Isn’t this an error?
The answer is that if you put the above code into the JavaScript engine and run it, you will indeed get an error. Because this syntax is not JavaScript, but React’s own JSX syntax for the convenience of developers.
JSX can be converted to normal JavaScript syntax by the Babel transcoder. The result of transcoding the above JSX syntax is as follows.
exports.default = function() {
return React.createElement(
"div",
null,
"hello world"
);
};
When comparing the two writing methods, you will find that for complex UI components, JSX is easier to write and more readable. Therefore, almost all React developers use JSX syntax.
The characteristic of JSX syntax is that, wherever the value of JavaScript is used, this kind of HTML-like syntax can be inserted.
const element = <h1>Hello, world!</h1>;
There are two points to note here. One is that all HTML tags must be closed, and <h1>Hello
errors will be reported if writing achievements. If it is a kind of label without closed syntax, you must add a slash at the end of the label, for example <img src="" />
. The second is any JSX expression, the top layer can only have one label, which means that there can be only one root element. The following wording will report an error.
// Throw an error
const element = <h1>hello</h1><h1>world</h1>;
// No error
const element = <div><h1>hello</h1><h1>world</h1></div>;
In the above code, the first method of writing will report an error, because the position of the root element has two <h1>
labels in parallel. Wrap one more layer on top of them and you won’t get an error.
Generally speaking, the HTML native tags are all lowercase, and the developer’s custom component tags are capitalized, for example <MyComponent/>
.
JSX syntax allows HTML and JS code to be mixed.
const element = (
<h1>
Hello, {formatName(user)}!
</h1>
);
In the above code, <h1>
the text content of the tag is embedded with JS code. The text generated each time depends on formatName(user)
the result of the function execution.
As you can see, as long as the curly brackets are used in the value part of JSX syntax {}
, it means entering the context of JS, and you can write JS code.
Please refer to the official documentation for more introduction .
React component syntax
Although the function that outputs JSX code is a React component, this writing method is only suitable for the simplest components. For more formal and general component writing, use ES6 class syntax.
import React from 'react';
class ShoppingList extends React.Component {
render() {
return (
<div className="shopping-list">
<h1>Shopping List for {this.props.name}</h1>
<ul>
<li>Instagram</li>
<li>WhatsApp</li>
<li>Oculus</li>
</ul>
</div>
);
}
}
export default ShoppingList;
The above code defines a ShoppingList component. The custom component must inherit React.Component
this base class, and then there must be a render
method that gives the output of the component.
Using the React component is also very simple. After introducing this component, you can use it directly. Assuming the above component script is called shoppinglist.js
, then the code to use it is as follows.
import React from 'React';
import ShoppingList from './shoppinglist.js';
class Content extends React.Component {
render() {
return (
<ShoppingList name="Mike" />
);
}
}
export default Content;
In the above code, we have created a new Content
component, which uses the ShoppingList
component. Note that since this component name
has no content other than parameters, it can be written in <ShoppingList name="Mike"/>
this directly closed form. Otherwise, it can be written in the following form.
class Content extends React.Component {
render() {
return (
<ShoppingList name="Mike">
{/* Other content inserted */}
</ShoppingList>
);
}
}
Component props
<ShoppingList name="Mike"/>
The line of code in the previous section ShoppingList
is the component name, name="Mike"
indicating that this component has a name
parameter with a value of Mike
.
Inside the component, all parameters are placed on the this.props
properties. this.props.name
You can get the incoming value by passing (Mike).
<h1>Shopping List for {this.props.name}</h1>
Through this parameter mechanism, React components can accept external messages.
this.props
The object has a very special parameter this.props.children
that represents all the content “wrapped” by the current component. For example, the elements in the code above Shopping List for {this.props.name}
are <h1>
elements this.props.children
. This attribute has a great effect on React. It means that the content that the user places inside the component can be obtained inside the component.
Let’s look at an example. The following is a component that is used internally to props.children
get the content passed in by the user.
const Picture = (props) => {
return (
<div>
<img src={props.src} />
{props.children}
</div>
)
}
Here’s how to props.children
pass in content when using it .
render () {
const picture = {
src: 'https://cdn.nlark.com/yuque/0/2018/jpeg/84141/1536207007004-59352a41-4ad8-409b-a416-a4f324eb6d0b.jpeg',
};
return (
<div className='container'>
<Picture src={picture.src}>
// The content placed here is props.children
</Picture>
</div>
)
}
Component state
In addition to accepting external parameters, there are different states within the component. React stipulates that the internal state of the component is recorded on this.state
this object.
class Square extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}
render() {
return (
<button
className="square"
onClick={() => this.setState({value: 'X'})}
>
{this.state.value}
</button>
);
}
}
In the above code, the current state object is defined in the component Square
‘s constructor. This object of the Square component has only one property, the initial value is.constructorthis.statevaluenull
After the user clicks the button, the onClick
listener function execution this.setState()
method. React uses this method to update the this.state
object. This method has a feature that after each execution, it will automatically call the render
method, causing the UI to be updated. Used in the UI to this.state.value
output status values. As the user clicks the button, the page will be displayed X
.
As you can see, in this example, the internal state is used to distinguish whether the user clicked the button.
Life cycle approach
There are different stages in the operation of components. React provides hook methods for these stages, allowing developers to customize the functions that are automatically executed in each stage. These methods are collectively referred to as lifecycle methods.
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
}
componentWillUnmount() {
}
componentDidUpdate() {
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
The above code componentDidMount()
, componentWillUnmount()
and componentDidUpdate()
are the three most common life-cycle approach. Among them, it componentDidMount()
will be called automatically after the component is mounted, it componentWillUnmount()
will be called automatically before the component is uninstalled, and it componentDidUpdate()
will be called every time the UI is updated (that is, after the component is successfully mounted, this method will be triggered every time the render method is called).
The following chapters, combined with examples, will introduce these methods in more detail.
In addition, there are three life cycle methods, which are not often used, and only need to be briefly understood here.
shouldComponentUpdate(nextProps, nextState)
: Every timethis.props
orthis.state
there is a change in therender
prior method executes, it will call this method. This method returns a Boolean value indicating whether therender
method should continue to be executed , that is, if it returnsfalse
, the UI will not be updated and returns by defaulttrue
. When the component is mounted, therender
method is not called for the first time the method is executed.static getDerivedStateFromProps(props, state)
: This method isrender
called before the method is executed, including the first record of the component. It should return a new state object, usually used when the state of the component depends on external input parameters.getSnapshotBeforeUpdate()
: This method is called before each DOM update to collect DOM information. The value it returns will be passed into thecomponentDidUpdate()
method as a parameter.
Discussion about this post