When writing the life cycle example, I found that it is not possible to demonstrate the life cycle effect with function components alone, so this section is dedicated to using class components as examples, as a complement to the knowledge of class components.
Upcoming demos are summarized below
The title | Demo |
---|---|
Component communication mode | The father the son Demo |
Child parent Demo | |
The life cycle | Demo: UNSAFE_componentWillMount, UNSAFE_componentWillUpdate, UNSAFE_componentWillReceiveProps |
Demo: getDerivedStateFromProps and getSnapshotBeforeUpdate | |
Full life cycle Demo |
Component communication mode (parent to child, child to parent)
Since the hook, we’ve almost always preferred to use function components (at least I do), but at some point function components don’t completely replace class components, which means that React developers still need to know about class components.
The father the son
In class components, note the reference to this in the method;
Although the setState method is also used to change the state, it is more complicated than hook.
Here’s the key code:
import React from "react";
import Child from "./Child";
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
parentData: 1
};
// Bind this to changeParentData
this.changeParentData = this.changeParentData.bind(this);
}
changeParentData() {
this.setState({ parentData: this.state.parentData + 1 });
this.forceUpdate();
}
render() {
return (
<div>
<button onClick={this.changeParentData}>Controls the display value of child elements</button>
<Child showData={this.state.parentData} />
</div>); }}export default Parent;
Copy the code
See Demo for the complete code
Child the parent
Also note the problems with the this binding
If your method is written like this:
sendChildData(data) {
this.setState({
childData: data
});
}
Copy the code
We didn’t add bind to this in the constructor
this.sendChildData = this.sendChildData.bind(this);
Copy the code
Or not adding bind to this in the render pass function
<Child sendChildData={this.sendChildData.bind(this)} / >Copy the code
The following error is reported
You can also turn sendChildData into an arrow function instead of calling bind
sendChildData = (data) = >{... }Copy the code
The key code is as follows
import React from 'react';
import ReactDom from 'react-dom';
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
childData: null
}
this.sendChildData = this.sendChildData.bind(this);
}
sendChildData(data) {
this.setState({
childData: data
});
}
render() {
return <div>
<Child sendChildData={this.sendChildData} />Display result:<span>{this.state.childData}</span>
</div>}}class Child extends React.Component {
constructor(props) {
super(props);
this.state = {
newData: "aaa"
}
sendData = () = > {
this.props.sendChildData(this.state.newData);
}
render() {
return <div>
<button onClick={this.sendData}>Modify parent component data</button>
</div>}}}Copy the code
See Demo for the complete code
The life cycle
Before getting into the lifecycle, it is important to note that there are three lifecycle approaches:
componentWillMount();
Execute before the component renderscomponentWillUpdate();
Execute before component updatecomponentWillReceiveProps();
The component executes before receiving the props data
When you use them, the compiler will tell you:
This method was deprecated in React 16.9.0, replacing it with UNSAFE_componentWillMount.
When you use the following three lifecycle methods:
UNSAFE_componentWillMount();
UNSAFE_componentWillUpdate();
UNSAFE_componentWillReceiveProps();
To view the Demo
And it will tell you:
This method won’t be deprecated until React 17, and it also introduces two new lifecyclesto you: getDerivedStateFromProps and getSnapshotBeforeUpdate.
New life cycle:
getDerivedStateFromProps;
Completely replace obsolete methodscomponentWillReceiveProps
getSnapshotBeforeUpdate;
Completely replace obsolete methodscomponentWillUpdate
For the use of getDerivedStateFromProps and getSnapshotBeforeUpdate, you can check out the Demo.
In fact, when you use strict mode, the three life cycle methods of UNSAFE_xxxx will not execute and will report warnings.
More details can be found at reactjs.org/link/unsafe…
The following life cycle diagrams are commonly used
ComponentDidMount: Dom is loaded.
ComponentDidUpdate: The component is updated.
ComponentWillUnmount: The component will be unmounted.
different | componentDidMount |
componentDidUpdate |
componentWillUnmount |
---|---|---|---|
Different execution cycles | The first mount each time the page is refreshed | With each update | The first and last uninstallation |
You are advised to perform the following operations:
ComponentDidMount: Relies on DOM operations, web requests, and adding subscriptions
ComponentWillUnmount: Clear timer, unsubscribe
Here’s the full lifecycle map:
ShouldComponentUpdata: Returns a Boolean if the component is updated when it receives a new state or props.
ShouldComponentUpdata accepts two arguments, one is props and one is state.
ShouldComponentUpdata (); shouldComponentUpdata (); shouldComponentUpdata (); shouldComponentUpdata ();
Again, getDerivedStateFromProps and getSnapshotBeforeUpdate, which also receive two parameters, props and State, are significantly different from shouldComponentUpdata.
different | getDerivedStateFromProps |
shouldComponentUpdata |
---|---|---|
Different execution cycles | First mount and each update, and beforeShouldComponentUpdata method perform |
Each time it is updated, and precedesRender phase perform |
Requirements for incoming parameters are different | State must have an initial value in the class | State is null if it is not specified |
Different return values | Return an object update state, or null to indicate that the new props does not need any state updates (the return value result does not affect the actual rendering) | Returns a Boolean value, true to allow rerendering of the view, otherwise stop rendering (the result of the return value affects actual rendering) |
GetSnapshotBeforeUpdate is not needed very often but has a specific use case so should be presented separately. Its return value is passed as a third parameter to componentDidUpdata, which is useful when manually saving the scroll position during rerendering.
See Demo for the full life cycle sample code
Note: Since getSnapshotBeforeUpdate, componentDidMount, componentDidUpdate, and componentWillUnmount execute after Render, it is my custom to place them after Render.
Note that getSnapshotBeforeUpdate can also read the DOM after render, but the pre-commit phase of the graph is different from the commit phase where side effects can be run.
The above illustrations are from the life cycle atlas
Fragment <></>
Since a component can only return a root element, we would normally wrap a
in the outer layer, but sometimes if we write a component that doesn’t want to wrap an unwanted
in the outer layer, we can use react. Fragment in the outer layer. For example:
import React from 'react'
export default class Test extends React.Component {
render() {
return (
<React.Fragment>
<header>header</header>
<main>main</main>
</React.Fragment>); }}Copy the code
Render as follows
React.Fragment also supports phrasal <>, such as the following:
import React from 'react';
export default class Test extends React.Component {
render() {
return (
<>
<header>header</header>
<main>main</main>
</>)}}Copy the code
Render the same