1.react life cycle
react life cycle: the whole process of many things from creation to destruction, this process is called the declaration cycle
React components also have their own life cycle, and understanding the life cycle of components allows us to complete the functions we want in the most appropriate place;
- The relationship between the life cycle and the life cycle function:
The life cycle is an abstract concept, in the whole process of the life cycle, it is divided into many stages;
1. For example, the loading stage (Mount), the process of the component being rendered in the DOM tree for the first time;
2. For example, in the update process (Update), the component state changes, and the rendering process is re-updated;
3. For example, the unmount process (Unmount), the process of the component being removed from the DOM tree; - In order to tell us which stages we are currently in, React will call back some functions implemented inside our components. These functions are life cycle functions:
1. For example, implement the componentDidMount function: when the component has been mounted on the DOM, it will call back;
2. For example, implement the componentDidUpdate function: when the component has been updated, it will call back;
3. For example, implement the componentWillUnmount function: when the component is about to be removed, it will call back;
We can write our own logic code in these callback functions to complete our own demand functions; - When we talk about the React life cycle, we mainly talk about the class life cycle, because functional components do not have life cycle functions; (later we can simulate some life cycle callbacks through hooks)
2.react life cycle analysis
import React, { Component } from 'react' class Cpn extends Component { render(){ return ( <div> I'm cpn components </div> ) } componentWillUnmount(){ console.log('executed cpn component componentWillUnmount method') } } export default class App extends Component { constructor(){ super(); console.log('implemented component constructor method') this.state = { count:0, isShow:true } } render() { console.log('implemented component render method') return ( <div> I'm app components <h2>Current count:{this.state.count}</h2> <button onClick={e => this.increment()}>+1</button> <button onClick={e => this.change()}>toggle</button> {this.state.isShow && <Cpn/>} </div> ) } componentDidMount(){ console.log('implemented component componentDidMount method') } componentDidUpdate(){ console.log('implemented component componentDidUpdate method') } increment(){ this.setState({ count:this.state.count + 1 }) } change(){ this.setState({ isShow:!this.state.isShow }) } }
3. What is usually done in the life cycle?
-
Constructor
If you don't initialize state or do method binding, you don't need to implement constructors for React components.
Two things are usually done in contrucotr:- Initialize the internal state by assigning the object to this.state
- Bind the instance for the event (this)
-
componentDidMount
componentDidMount() is usually called immediately after the component is mounted
Two things are usually done in componentDidMount():- DOM-dependent operations can be performed here
- Sending network requests here is the best place
- Some subscriptions can be added here (unsubscribe at componentWillUnmount)
-
componentDidUpdate
componentDidUpdate() will be called immediately after the update, and this method will not be executed for the first rendering.
Two things are usually done in componentDidUpdate():- When the component is updated, the DOM can be manipulated here;
- If you compare the props before and after the update, you can also choose to make a network request here; (for example, when the props haven't changed, the network request will not be performed).
-
componentWillUnmount
componentWillUnmount() will be called directly before the component is unmounted and destroyed.
These things are usually done in componentWillUnmount():- Perform necessary cleanup operations in this method;
- For example, clear the timer, cancel the network request or clear
- Subscriptions etc. created in componentDidMount();
Communication between react components
1. There is a nested relationship between components:
- In the previous case, we just created a component App;
- If our application puts all the logic in a component, then this component will become very bloated and difficult to maintain;
- Therefore, the core idea of ​​componentization should be to split components into small components;
- These components are then combined and nested together to finally form our application;
import React, { Component } from 'react' // Header function Header(){ return ( <h2>I'm header components</h2> ) } // Main function Main(){ return ( <div> <Banner/> <ProductList/> </div> ) } //banner function Banner(){ return ( <h2>I'm Banner components</h2> ) } //productList function ProductList(){ return ( <div> <ul> <li>Product list 1</li> <li>Product list 2</li> <li>Product list 3</li> <li>Product list 4</li> <li>Product list 5</li> </ul> </div> ) } // Footer function Footer(){ return ( <h2>I'm Footer components</h2> ) } export default class App extends Component { render() { return ( <div> <Header/> <Main/> <Footer/> </div> ) } }
2. Communication between parent and child components:
-
During the development process, we will often encounter the need for components to communicate with each other:
1. For example, the App may use multiple Header, and the content displayed by the Header in each place is different, then we need the user to pass some data to the Header to display it;
2. Another example is that we have requested Banner data and ProductList data at one time in Main, then we need to pass them to them for display;
3. It may also be that an event has occurred in the child component, and some operations need to be completed by the parent component, then the child component needs to pass the event to the parent component; -
In short, in a React project, the communication between components is a very important link;
The parent component is presenting the child component and may pass some data to the child component:
The parent component passes data to the child component in the form of attribute = value;
The child component obtains the data passed by the parent component through the props parameter;
3. Parent component passes data to child component - class component
//parent-child class component class ChildCpn extends Component { render(){ const {name , password} = this.props.data; return ( <h2>Subcomponents display data:{name + password}</h2> ) } } export default class App extends Component { constructor(){ super() this.state = { data:{ name:'admin', password:'123456' } } } render() { return ( <div> <ChildCpn data = {this.state.data}/> </div> ) } }
4. Parent component passes data to child component - function component
//parent-child function component function ChildCpn(props){ const {name, password} = props.data; return ( <div> <h2>Name:{name} password: {password}`</h2> </div> ) } export default class App extends Component { constructor(){ super() this.state = { data:{ name:'admin', password:'123456' } } } render() { return ( <div> <ChildCpn data = {this.state.data}/> </div> ) } }
5. Parameter passing -- parameter attribute validation
- For data passed to child components, sometimes we may want to validate, especially for large projects:
1. Of course, if your project inherits Flow or TypeScript by default, then type verification can be performed directly;
2. However, even if we are not using Flow or TypeScript, parameter validation can be done through the prop-types library;
import React, { Component } from 'react' //parameter type check import PropTypes from 'prop-types' //parent-child function component function ChildCpn(props){ console.log(props) let personList = props.data; return ( <div> <ul> { personList.map((item,index) => { return <li>{item.name} : {item.password} </li> }) } </ul> </div> ) } //We need data type to be array type ChildCpn.propTypes = { data:PropTypes.array } //Attribute default value Parent component passed data is empty ChildCpn.defaultProps = { data:[ {name:'No data',password:'xxxxxx'} ] } export default class App extends Component { constructor(){ super() this.state = { data:[ {name:'zhangsan',password:'123456'}, {name:'lisi',password:'abcdef'}, {name:'wangwu',password:'777777'} ] } } render() { return ( <div> <ChildCpn data = {this.state.data}/> </div> ) } }