Understand the react lifecycle function

Erdong snail 2021-09-15 09:05:01
understand react lifecycle function


Life cycle overview

projects.wojtekmaj.pl/react-lifec… image.png

The life cycle of the yellow box is React17.0 Removed lifecycle functions  Life cycle (1).png

Life cycle description

image.png

/* eslint-disable no-script-url */
/* eslint-disable jsx-a11y/anchor-is-valid */
import React, { Component } from "react";
class LifeCycle extends React.Component {
constructor(props) {
super(props);
this.state = {
num: Math.random() * 100,
};
this.childRef = React.createRef();
console.log('parent constructor')
}
static getDerivedStateFromProps(nextProps, prevState) {
console.log("parent getDerivedStateFromProps");
if (nextProps.isUpdate) {
return { str: "getDerivedStateFromProps update state" };
}
return null;
}
// componentWillReceiveProps(nextProps, prevState) {
// debugger
// console.log("componentWillReceiveProps()");
// }
componentDidMount() {
console.log("parent componentDidMount");
// this.setState({
// str: "str",
// });
}
shouldComponentUpdate(nextProps, nextState) {
console.log("parent shouldComponentUpdate");
return true; // Remember to return true
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("parent getSnapshotBeforeUpdate");
return {
name: "componentWillUpdate",
};
}
// componentWillUpdate(prevProps, prevState) {
// console.log("componentWillUpdate");
// return {
// name: 'componentWillUpdate'
// }
// }
componentDidUpdate(prevProps, prevState, snapshot) {
console.log("parent componentDidUpdate");
}
componentWillUnmount() {
console.log("parent componentWillUnmount");
}
propsChange() {
console.info(" Update parent component state");
this.setState({
num: Math.random() * 100,
});
}
setLifeCycleState() {
console.info(" Update subcomponents state");
this.childRef.current.setTheState();
}
forceLifeCycleUpdate() {
console.info(" Force update of subcomponents ");
this.childRef.current.forceItUpdate();
}
parentForceUpdate() {
console.info(" Force update of parent component ");
this.forceUpdate();
}
render() {
console.log("parent render")
return (
<div> <button className="weui_btn weui_btn_primary" onClick={this.propsChange.bind(this)} > Update parent component state </button> <button className="weui_btn weui_btn_primary" onClick={this.setLifeCycleState.bind(this)} > Update subcomponents state </button> <button className="weui_btn weui_btn_primary" onClick={this.forceLifeCycleUpdate.bind(this)} > forceUpdate Child components </button> <button className="weui_btn weui_btn_primary" onClick={this.parentForceUpdate.bind(this)} > forceUpdate Parent component </button> <Message ref={this.childRef} num={this.state.num}></Message> </div>
);
}
}
class Message extends Component {
constructor(props) {
super(props);
console.log("child constructor");
this.state = { str: "hello", name: "rodchen" };
}
static getDerivedStateFromProps(nextProps, prevState) {
console.log("child getDerivedStateFromProps");
if (nextProps.isUpdate) {
return { str: "getDerivedStateFromProps update state" };
}
return null;
}
// componentWillReceiveProps(nextProps, prevState) {
// debugger
// console.log("componentWillReceiveProps()");
// }
componentDidMount() {
console.log("child componentDidMount");
// this.setState({
// str: "str",
// });
}
shouldComponentUpdate(nextProps, nextState) {
console.log("child shouldComponentUpdate");
return true; // Remember to return true
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("child getSnapshotBeforeUpdate");
return {
name: "componentWillUpdate",
};
}
// componentWillUpdate(prevProps, prevState) {
// console.log("componentWillUpdate");
// return {
// name: 'componentWillUpdate'
// }
// }
componentDidUpdate(prevProps, prevState, snapshot) {
console.log("child componentDidUpdate");
}
componentWillUnmount() {
console.log("child componentWillUnmount");
}
setTheState() {
let s = "hello";
if (this.state.str === s) {
s = "HELLO";
}
this.setState({
str: s,
});
}
forceItUpdate() {
this.forceUpdate();
}
render() {
console.log("child render");
return (
<div> <span> Props:<h2>{this.props.num}</h2> </span> <span> State:<h2>{this.state.str}</h2> </span> </div>
);
}
}
export default LifeCycle;
 Copy code 

monting Stage

image.png

Contructor

import React from "react";
class LifeCycle extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'rodchen'
}
}
render() {
return (
<div> <h2>Life Cycle</h2> <div> </div> </div>
);
}
}
export default LifeCycle;
 Copy code 

If not initialized state Or no method binding , It doesn't need to be React Component implementation constructor .

stay React Before mounting the components , Will call its constructor . For React.Component When a subclass implements a constructor , It should be called before other statements super(props). otherwise ,this.props Undefined... May appear in the constructor bug.

Usually , stay React in , Constructors are only used in the following two cases :

  • By giving this.state Assign an object to initialize the interior state.
  • Binding instances for event handlers

stay constructor() Do not call setState() Method . If your component needs to use internal state, Please directly in the constructor for this.state Assignment initial state:

Avoid props Copy the value of to state

constructor(props) {
super(props);
// Don't do this 
this.state = { color: props.color };
}
 Copy code 

When props The update will not be updated to state. Only when you deliberately ignore prop Use in case of update . here , Should be prop Rename it to initialColor or defaultColor. When necessary, , You can modify its key, To force “ Reset ” Its internal state.

getDerivedStateFromProps

getDerivedStateFromProps Will be in the call render Call before method , And it will be called during initial mount and subsequent update . It should return an object to update state, If you return null Then nothing will be updated .

 static getDerivedStateFromProps(nextProps, prevState) {
console.log("getDerivedStateFromProps");
return {str: "getDerivedStateFromProps update state"};
}
 Copy code 

This method does not have access to the component instance . If you need , You can extract components by props Pure functions of and class Out of state , stay getDerivedStateFromProps() And others class Reuse code between methods . Use here this yes undefined.

Please note that , Whatever the reason , This method is triggered before each rendering . This is related to UNSAFE_componentWillReceiveProps Contrast formation , The latter is triggered only when the parent component is re rendered , Instead of calling... Internally setState when .

getDerivedStateFromProps

image.png

UNSAFE_componentWillReceiveProps

componentWillReceiveProps You can access the component instance ,this Is the current component

image.png Because for whatever reason , This method is called every time you render , So default back to null. If props Incoming content doesn't need to affect your state, Then you need to return a null, This return value is required , So try to write it to the end of the function ​


static getDerivedStateFromProps(nextProps, prevState) {
console.log("getDerivedStateFromProps");
if (nextProps.isUpdate) {
return {str: "getDerivedStateFromProps update state"};
}
return null;
}
 Copy code 
 render() {
// console.log("render");
return (
<div> <span>Props:<h2>{this.props.num}</h2></span> <br/> <span>State:<h2>{this.state.str}</h2></span> </div>
);
}
 Copy code 

render

render() The method is class The only method that must be implemented in a component .

When render When called , It will check. this.props and this.state And return one of the following types :

  • React Elements . Usually by JSX establish . for example ,
    Will be React Render as DOM node , Will be React Render as a custom component , Whether it's
    still Are all React Elements .
  • An array or fragments. bring render Method can return multiple elements . For more details , see also fragments file .
  • Portals. You can render children to different DOM In the subtree . For more details , Please refer to the portals Documents
  • String or numeric type . They are DOM Is rendered as a text node in
  • Boolean type or null. Nothing to render .( Mainly used to support return test && The pattern of , among test Is Boolean type .)

render() Function should be pure function

This means that components are not modified state Under the circumstances , Return the same result every time , And it doesn't interact directly with the browser .

To interact with the browser , Please be there. componentDidMount() Or other life cycle methods . keep render() It's a pure function , Can make components easier to think about .

If shouldComponentUpdate() return false, Will not call render().

 shouldComponentUpdate() {
console.log("shouldComponentUpdate");
return true; // Remember to return true
}
 Copy code 

image.png

 shouldComponentUpdate() {
console.log("shouldComponentUpdate");
return false; // Remember to return true
}
 Copy code 

image.png

componentDidMount

componentDidMount() {
console.log("componentDidMount");
}
 Copy code 

componentDidMount() After the component is mounted ( Insert DOM In the tree ) Call immediately . Depend on DOM The initialization of the node should be here . If you need to request data through the network , This is a good place to instantiate requests .

This method is more suitable for adding subscriptions . If a subscription is added , Please don't forget to be in componentWillUnmount() Unsubscribe from

image.png

You can componentDidMount() Directly call setState(). It will trigger additional rendering , But this rendering happens before the browser updates the screen . This ensures that even in render() In the case of two calls , The user will not see the intermediate state .

 componentDidMount() {
console.log("componentDidMount");
this.setState({
str: 'str'
})
}
 Copy code 

image.png

Why? componentDidMount Before the parent node ?

  • Common sense understanding : The parent and child nodes are hung on dom node , If the child node is not mounted successfully , The parent component cannot indicate that it has been successfully mounted .
  • Process description :Diff Algorithm ,render At the stage , For each node completeWork In the method , The current effectTag Node identification and establishment of linked list structure effectList.completeWork The nodes of are also executed from the child nodes up , So in render After the phase is successful , The root node will have an all ID effectTag List to be updated .firstEffectTag Point to the first leaf node that needs to be updated . This linked list is made here to optimize , You can't render Phase in diff Algorithm , here we are commit It needs to be done again diff Algorithm .

Updating

Update example

Manually update the parent component state

image.png

Manually update subcomponents state

image.png

Force update of parent component state

image.png

Force update of subcomponents state

image.png

shouldComponentUpdate

 shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate");
return true; // Remember to return true
}
 Copy code 

according to shouldComponentUpdate() The return value of , Judge React Whether the output of the component is subject to the current state or props The impact of the change . The default behavior is state Every time something changes, the component re renders . In most cases , You should follow the default behavior .

When props or state When something changes ,shouldComponentUpdate() Will be called before rendering execution . The return value defaults to true.

This method only exists as a way of performance optimization . Don't try to rely on this method “ prevent ” Rendering , Because it might produce bug. You should consider using the built-in PureComponent Components , Not by hand shouldComponentUpdate().PureComponent Would be right props and state Make shallow comparison , And reduces the possibility of skipping necessary updates .

If you have to write this function manually , Can be this.props And nextProps as well as this.state And nextState Compare , And back to false Informing React You can skip updates . Please note that , return false It does not prevent subcomponents from being in state Re render on change .

We do not recommend shouldComponentUpdate() To make a deep comparison or use JSON.stringify(). This has a great impact on efficiency , And it can damage performance .

Render or use... For the first time forceUpdate() This method will not be called when

The initial load :

image.png

forceUpdate:

image.png

return false

If shouldComponentUpdate() return false, Will not call UNSAFE_componentWillUpdate(),render() and componentDidUpdate()

image.png

 shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate");
return false; // Remember to return true
}
 Copy code 

image.png

getSnapshotBeforeUpdate

getSnapshotBeforeUpdate() In the last render output ( Submitted to the DOM node ) Previous call . It allows components to change from DOM Capture some information in ( for example , Scroll position ). Any return value for this lifecycle will be passed as a parameter to componentDidUpdate().

This usage is not common , But it could be in UI In processing , If you need to deal with the chat thread in the scrolling position in a special way .

Should return snapshot Value ( or null).

This new update replaces componentWillUpdate. common componentWillUpdate Before the component is updated , Read the current DOM State of element , And in componentDidUpdate And deal with it accordingly .


getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("getSnapshotBeforeUpdate");
return {
name: 'componentWillUpdate'
}
}
// componentWillUpdate(prevProps, prevState) {
// console.log("componentWillUpdate");
// return {
// name: 'componentWillUpdate'
// }
// }
componentDidUpdate(prevProps, prevState, snapshot) {
console.log("componentDidUpdate");
debugger
console.log(snapshot)
}
 Copy code 

image.png

componentWillUpdate & getSnapshotBeforeUpdate The difference between

www.jianshu.com/p/b91e95af2…

  • stay React When asynchronous rendering mode is on , stay render Phase reads DOM The state of an element is not always related to commit Same stage , This leads to componentDidUpdate Use in componentWillUpdate Read from DOM Element states are unsafe , Because the value at this time is likely to be invalid .
  • getSnapshotBeforeUpdate It will be in the end render Called before , That is to say getSnapshotBeforeUpdate Read from DOM The state of an element is guaranteed to be identical with componentDidUpdate In accordance with .
  • Any value returned by this lifecycle will be passed as a parameter to componentDidUpdate().

componentDidUpdate

componentDidUpdate(prevProps, prevState, snapshot)
 Copy code 

componentDidUpdate() Will be called immediately after the update . The first rendering does not do this .

When the component is updated , You can do it here DOM To operate . If you are on the update before and after props Made a comparison , You can also choose to make a network request here .( for example , When props When there is no change , The network request will not be executed ). You can also be in componentDidUpdate() Call directly setState(), But notice that it has to be wrapped in a conditional statement , Deal with it as in the example above , Otherwise, it will lead to a dead cycle .

componentDidUpdate(prevProps) {
// characteristic use ( Don't forget to compare props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
 Copy code 

getSnapshotBeforeUpdate & componentDidUpdate The order of

Look at the above manual update parent component state, Generated updates . The sequence of life cycle execution is as follows . here getSnapshotBeforeUpdate and componentDidUpdate The order of execution is separate , The same starts with sub components , Then go to the parent component . image.png

This is from commit For the three stages of :commit There are three stages

  • before mutation Stage : operation DOM Before 【getSnapshotBeforeUpdate】
  • mutation Stage : operation DOM【componentWillUnmount】
  • layout Stage : operation DOM after 【componentDidMount,componentDidUpdate】

And above Why? componentDidMount Before the parent node ? The same thing ,commit The main stage is traversal render Stage formation effectList. because effectList The order of is from the leaf node . So the order here is from child node to parent node . So why is it divided into two batches . Because these two methods are in commit Performed at different stages of .

Unmounting

componentWillUnmount

componentWillUnmount()
 Copy code 

componentWillUnmount() It will be called directly before the component is unloaded and destroyed . Perform the necessary cleanup operations in this method , for example , eliminate timer, Cancel network request or clear in componentDidMount() Subscriptions created in, etc .

componentWillUnmount() Should not call setState(), Because the component will never re render . After the component instance is uninstalled , Will never mount it again .

Uninstall components ​

image.png

The reason here is that when the parent node is diff Algorithm time , Identify that the current node needs to be deleted , The continuous traversal of the current node will be ended . And in the commt Of mutation Stage , Conduct delete case When , It will traverse the parent node and all child nodes , Remove for delete operation .

performance optimization

React.PureComponent

React.PureComponent And React.Component Very similar . The difference between the two is React.Component Did not achieve shouldComponentUpdate(), and React.PureComponent In contrast to the shallow prop and state This function is implemented in the following way . ​

If given React Components are the same props and state,render() Function will render the same thing , So in some cases, use React.PureComponent Improve performance .

React.memo

React.memo For higher-order components . ​

If your components are in the same props Render the same result , Then you can pack it in React.memo Call in , In this way, the performance of components can be improved by memorizing the rendering results of components . This means that in this case ,React The operation of the rendering component will be skipped and the result of the last rendering will be reused directly . ​

React.memo Check only props change . If the function component is React.memo The parcel , And its implementation has useState,useReducer or useContext Of Hook, When state or context When something changes , It will still re render . ​

By default, it only performs shallow contrast on complex objects , If you want to control the contrast process , Please pass in the second parameter to implement the custom comparison function .

版权声明
本文为[Erdong snail]所创,转载请带上原文链接,感谢
https://qdmana.com/2021/09/20210909142454913t.html

  1. Contrôle de l'arbre en vue converti en style de table
  2. CSS3 animation flash Effect
  3. Discuter des propriétés de la file d'attente pour l'événement bloc
  4. Node around USModules
  5. Webpack - - Premier aperçu (concept de base)
  6. Mise en œuvre du cadre de base mvvm par JS natif
  7. Calculer les propriétés par rapport aux auditeurs, etc.
  8. Configuration standard dockerfile et docker-composer.yml
  9. Collection de questions d'entrevue HTML
  10. Conteneur, définir la largeur et la hauteur ne répond pas?
  11. Introduction et syntaxe des objets (mise à jour à long terme)
  12. Bubble Mart invests in cat galaxy, which is a vertical e-commerce platform around the quadratic element
  13. Exigences et dépendances dans package-lock.json
  14. Mouvement tridimensionnel de la terre, du ciel et de la lune basé sur three.js
  15. Compréhension et analyse de l'objet de base JS
  16. Simple use of status data management (context, mobx, Redux)
  17. Simulated drumming
  18. Array method
  19. Performance optimization issue 03 - HTTP request optimization
  20. Vue learning -- watch listener
  21. Learn more about nexttick in Vue
  22. Talk about some moves used by vue3.0 in the project - External skill chapter (I)
  23. JavaScript genrator generator
  24. La dernière réponse à l'entrevue de développement Android, l'hiver froid de l'industrie
  25. Maserati's motorcycle has less than 10 in the world. It is definitely a work of art
  26. 2021 partage des questions du dernier examen écrit d'entrevue Android, pas d'accord
  27. Programmation asynchrone Java scirp, développement frontal de base
  28. 2021 dernier examen écrit d'entrevue Android, écrit trop bien
  29. Quels aspects doivent être pris en considération dans le tableau principal du distributeur libre - service?
  30. He inherited his mother's hundreds of millions of property for his boyfriend to squander. Unexpectedly, he was ruthlessly abandoned when he had 100 yuan left
  31. The fuel cost is half less than that of fuel vehicles at the same level. Is it really cheap to use song Pro DM?
  32. Le dernier résumé de l'expérience d'entrevue d'embauche de l'école Android de l'usine est nécessaire pour l'usine
  33. Le dernier dictionnaire avancé de programmeurs d'usine, l'expérience d'entrevue d'embauche de l'Agence de développement Android
  34. La dernière collection d'entrevues Android Golden nine Silver ten
  35. L'expérience d'entrevue de l'Ingénieur d'algorithme de saut d'octets, 2 mois d'entrevue Tencent, station B, Netease et ainsi de suite sur 11 entreprises résumé!
  36. La dernière collection d'entrevues d'Android Golden nine Silver ten recommande un projet github
  37. Yuan Li's recent situation revealed that he was obsessed with public welfare, dressed simply and fearless, grew fat, and married an 11-year-old husband
  38. Initial experience of template tool plop of [front end Engineering]
  39. Dernière question d'entrevue avancée et réponse d'Alibaba Android, Alibaba P8 vous apprendra en personne
  40. Partage des dernières questions d'entrevue pour Android haute fréquence, Introduction aux compétences d'entrevue pour le développement d'Android
  41. Partager les dernières questions d'entrevue Android haute fréquence avec quelques conseils
  42. About JavaScript modules
  43. Iteratable object and class arrays
  44. Function realization of Vue elementui exporting excel form
  45. Use canvas to realize a small screenshot function
  46. Object oriented programming (2)
  47. Several common value transfer methods between Vue components
  48. Démarrer avec le serveur de base zéro: Hello World
  49. J'a I construit un escalier pour aller sur la lune, combien de façons puis - je poursuivre la sœur Chang'e?
  50. CSS implémente la fonction d'expansion et d'arrimage du Texte multiligne
  51. Varlet CLI | vue3 Component Library Quick Prototyping Tool
  52. Belle vue sur les trois rivières Xiapu
  53. La partie Web qui déploie SharePoint ajoute son propre module de fonctionnalité
  54. React Native (mise à jour à long terme)
  55. La conception et le codage de l'arbre binaire requis pour chaque entrevue d'embauche de la société Java millet;
  56. 10 jours pour obtenir l'offre d'emploi Android d'Alibaba, entrevue Android
  57. A remporté avec succès Byte, Tencent, Pulse offer, 7 ans Java une expérience d'entrevue de baise,
  58. 10大前端常用算法,web应用与开发
  59. Nginx - minimum configuration! You deserve it
  60. Les questions d'entrevue couramment utilisées pour le cadre Java sont - elles prometteuses pour le développement Java?