React components of the communication between the way to understand the next

Source: Internet
Author: User
Tags error handling


Let's start with a few terms:


official my story. corresponding Code
React element React elements let element=<span>A爆了</span>
Component Component class App extends React.Component {}
No The app is a parent element and APP1 is a child element <App><App1></App1></App>


This article focuses on:


    • Components have two properties
      • 1, the introduction of a "props"
      • 2. Returned a REACT element
    • Constructors for components
      • If it needs to be redefined, it must be activated, that is, itconstructorsupercan bethisused from the React.component method
    • Component'sprops
      • Is readable, that is, the Prop property cannot be modified in the component
      • The props of the object passed in Jsx, which can be passed through the {... object} method
    • Communication between parent and child elements (primary version)
      • Parent = child, therendercontent of the child element can be changed through the parent element.
      • The child, the parent element, passes through thepropstop-mounted method in the child element, allowing the child element to trigger the method in the parent element to communicate.
Component


On the last mention of JSX's usage, this time to speak of a communication between react components. So what is a component? I know English is component, but this is a word for me, meaningless. To understand how friendly communication between component, it is necessary to understand component is a ghost.



On the last jsx, we can create objects like this:

Let element=<h1 className="aaa">A burst</h1>
//Equivalent to
Let element=React.createElement(
  "h1",
  {className:"aaa"},
  "A burst"
)
Still honestly use the standard HTML tag element h1, div to generate React elements. But in this case, our JS will become huge, all of them are new React elements, it is possible that we don't even know what the object name is, or maybe it becomes let div1; let div2. Hahaha made a joke. But separation is definitely going to be separated. This time there is a concept called Component. What can he do? Simply put, create a separate, reusable widget. Not much to say, let's come from the official way of writing:

Write one: function-based creation of components, you can see that I directly define a method called App, each time you execute App () will return a new React element. And this method we can call the component Component. Some friends who have already started React may be stupid. What is this operation, my tall class? Extend? I regret to tell you that this is also a component, because he meets the official definition: 1, passed a "props", 2, returned a React element. Satisfying the above two conditions is Component!

Function App(props) {
  Return <span>{props.name}! A burst </span>
}
This is the easiest Component. In my opinion, Component itself is a wrapper around React.createElement. Its render method is equivalent to the functionality of React.createElement. The components on the tall are coming:

Import React, { Component } from 'react';
Class App extends Component {
  Render() {
    Return <span>{this.props.name}! A burst </span>
  }
}
Export default App;
The components of this class version and the components of the pure method above are not different from the perspective of React, but! After all, my class method also inherits React.Component, not a little bit of small features can not be said right? So the component we want to inherit from React.Component has more initial functionality than the pure method return. So each React component can be used directly as a React element.

Ok, let's study the method of the Component class.

The first is a magic constructor function, which is a function in the class that can be used for initialization. If you don't write it, you won't go wrong, because our components are subclasses of React.Component, so they inherit the constructor method of React.Component. If we define a constructor in a subclass Component that is equivalent to a method that overrides the parent class, the constructor of React.Component will be invalid. Simply put, many default assignments are invalid. You can't get props. Therefore, in order to remind everyone not to forget super, that is, inherit the constructor of the parent class, so it will report "this hasn't been initialised - super() hasn't been called" this error. The meaning is that you first inherit. In other words, super is the method that executes the constructor of the parent class. and so! ! ! The point is coming - we can't forget to pass in props when we write super. Without passing in props, the program cannot get the defined component properties.

Constructor(props) {
    Super(props);//equivalent to React.Component.call(this,props)
}
The official also gives you a focus:

Class components should always call the base constructor with props. (The class should be built with the props when executing the basic constructor.)

For us, we didn't write a constructor, but in other built-in methods, such as render, we can also get props directly. This weird operation can be explained. Because we have omitted the redefinition, but the constructor itself is not only existing but also executed, but it is not reflected in the subclass we wrote.

Props pit
After analyzing the Component, did you find a limitation of Component? That's right! It is the rumor! One definition of Component is that you can only pass arguments to props. In other words, all communication must be carried out in this props. There is a kind of visual inspection that can only be seen in the prescribed window, holding a walkie-talkie chat, other ways can not communicate. React has harsh regulations for props.

All React components must act like pure functions with respect to their props.

Simply put, props can't be changed and is read-only. (If you don't believe in evil, you have to try it. You can directly change the value of props. Finally, you must be waiting for an error page.)

Here you need the concept of pure function pure function under the popular science, and then Redux will also encounter. This means that a pure function is just a process that does not change the value of any object. Because the JS object has a very strange phenomenon. If you pass an object to this method and change the value of one of its properties, the passed in object will change outside of the function. The pure function is that your changes cannot affect objects outside the scope of the function. So every time we encounter a new object state in the Component, the data of this component will be processed by the state in the current component.

Focus: Because of the nature of JS, props is set to read-only, in order not to pollute the global scope. This largely guarantees the independence of the Component. Equivalent to a Component is a small world.

I found that defining the value of props is also a matter of learning, and it is easy to step on the pit.

For example, the code below, I think the print should be props: {firstName: "Nana", lastName: "Sun"...}, the result is props: {globalData: true}.

Let globalData={
    firstName: "Nana",
    lastName: "Sun",
    Greeting:["Good moring","Good afternoon","Good night"]
}
ReactDOM.render(<App globalData/>, document.getElementById('root'));
So for props how to pass the component, I think it is necessary to study it.

Props is actually a parameter directly into the component, and does not do anything special. So the processing of props is in the step of React.createElement. Let's review how React.createElement works.

React.createElement(
  "yourTagName",
  {className:"aaa",color:"red:},
  "Text/Subnode"
)
//The corresponding JSX is written as:
<yourTagName className="aaa" color="red>Text/Subnode</yourTagName>
That is, his grammar is a property name = property value. If we put an <App globalData/> directly, it will be parsed into <App globalData=true/>}, so props certainly can't get the result we want. . This is his grammar, we can't reverse it, but we can change it to something that can't be parsed into attribute name= attribute value. This is {...globalData}, deconstructed and then refactored, so that's it.

Message passing between Components Update of a single component -> setState
Message passing between Components is an interactive process, which means that Component is "dynamic" rather than "static". So first we have to let the static Component "move up", that is, update the value of the component, not mentioned in the previous props can not be changed, then how to change? As mentioned above, Component is a small world, so this world has a state called state.

First consider how the external force changes the state of the Component, such as clicking and scrolling.

Class App extends Component {
  State={
      Num:0
  }
  addNum=()=>{
    this.setState({
      Num:this.state.num+1
    })
  }
  Render() {
    Return( [
        <p>{this.state.num}</p>,
        <button onClick={this.addNum}>Click me +1</button>
      ]
    )
  }
}
Here I used the onClick user initiative to force the component to update. In fact, the small world of component is mainly updated by state, but it will not directly change the value of this.state.XXX=xxx, but by this.setState({...}).

There is a small tip here, I feel that everyone is very easy to make mistakes, this on the arrow function points to the problem, everyone sees. When the arrow function is converted to ES5, we can clearly see that the arrow function points to the function object of the previous layer. This also points to the App object.

If you don't want to use the arrow function, then you should pay attention, we can add a bind (this) in onClick to bind the pointing of this, like this onClick={this.addNum.bind(this)}.

  Render() {
    Return( [
        <p>{this.state.num}</p>,
        <button onClick={this.addNum.bind(this)}>Click me +1</button>
      ]
    )
  }
Communication between components
Then Component can be self-high through this.setState, then what about the components? Component can't close itself, don't cooperate with other components? Then we can try a way.

In the app I extract <p>{this.state.num}</p> and put it in App1, then App1 is directly displayed with props, because props is from the parent element. Equivalent to passing num directly to the App (parent element) to App1 (child element). Each time the state changes in the App, App1 receives the call and updates it together. So what kind of theory is this summoning based on? At this time I will introduce the life cycle of React.

//App
Render() {
  Return( [
      <App1 num={this.state.num}/>,
      <button onClick={this.addNum}>Click me +1</button>
    ]
  )
}
//App1
Render() {
  Return( [
      <p>{this.props.num}</p>,
    ]
  )
}
React life cycle
Seeing the life cycle of life cycle, I feel the endless cycle of life! Am I going to explain it in this circle? What is the life cycle in react? If it's just a simple rendering, there is no life cycle to say, after all, as long as the content is rendered, the task is completed. So the life cycle here must be related to change. If there is a change, it needs to be re-rendered, then changed, and then rendered. This is a circle. This is the life cycle. So how does the change in elements in React change?

First come to an official life cycle (I look dizzy):

Point me to see the live version

Official full cycle:

The official minimalist cycle:

Have you seen a headache, anyway, I am embarrassed.
It’s a huge life cycle. I still use actual combat to confirm how this update is generated. Actually out the truth! (Some unsafe methods, or some that we don't really use, are not discussed here.)

Mounting equipment stage:

Constructor()
Render()
componentDidMount()
Updating update phase:

Render()
componentDidUpdate()
Controversial componentWillReceiveProps()
Unmounting uninstallation phase:

componentWillUnmount()
Error Handling error capture extreme

componentDidCatch()
Here we run the code to confirm the life cycle, here is a part of the code of the parent element nested child element, is to tell everyone that I printed the 啥 at each stage. The examples in this section are still examples of App and App1 above.

//father
Constructor(props){
  Console.log("father-constructor");
}
componentDidMount() {
  Console.log("father-componentDidMount");
}
componentWillUnmount() {
  Console.log("father-componentWillUnmount");
}
componentDidUpdate() {
  Console.log("father-componentDidUpdate");
}
Render() {
  Console.log("father-render");
}
//child
Constructor(props){
  Console.log("child-constructor");
  Super(props)
}
componentDidMount() {
  Console.log("child-componentDidMount");
}
componentWillUnmount() {
  Console.log("child-componentWillUnmount");
}
componentDidUpdate() {
  Console.log("child-componentDidUpdate");
}
componentWillReceiveProps(){
  Console.log("child-componentWillReceiveProps");
}
Render() {
  Console.log("child-render");
}
Ok~ Start looking at the graph reasoning~

Initialize the running status:

There is no problem with the parent element running first, but the problem is that the parent element has not yet finished running, killing a child element. In other words, when the parent element encounters the child element in the render, the child element is loaded first. After the child element is loaded, the parent element is loaded and the parent element continues to load until the end.

I clicked on the parent element setState and then updated the props of the child element.

The same parent element render, first suspends when it encounters a child element. The child element has componentWillReceiveProps at this time, which means that he first knows that the parent element has passed props, and then renders. Because sometimes we need to perform some kind of operation after getting the props changed by the parent element, componentWillReceiveProps is useful, otherwise the child element will be directly rendered. If you have a props, then there is no props in my child element. Isn't it going to execute componentWillReceiveProps? ? That is <App1 num={this.state.num}/> becomes <App1/>. I am still too naive. This componentWillReceiveProps will still execute:

componentWillReceiveProps is not a change in the props passed to the parent element, but the parent element is rendered, and this method of the child element is set.

Regarding the uninstallation, let's play it and change the App method to the following. When num is equal to 2, App1 is not displayed.

Render() {
  Return(
    <div>
      {this.state.num===2?"":<App1 num={this.state.num}/>}
      <button onClick={this.addNum}>Click me +1</button>
    </div>
  )
}
The app first renders, then uninstalls App1 and finishes updating componentDidUpdate.

So, do you understand the life cycle? ? I have summarized the following:

When the parent element is loaded with the child element loaded, the child element is loaded first, and then the parent element continues to be loaded.
When the parent element renders, the child element will trigger componentWillReceiveProps and follow the render
When the parent element unloads a child element, it first renders, then unloads the child element, and finally componentDidUpdate
How to pass on my father? ?
Through the life cycle, child elements can easily get the content of the parent element, but how does the parent element get the content from the child element? Let's not forget them as a communication bridge props! We can create a method in the parent element to get the information of the child element, then bind to the child element, and then you can get it! The operation is as follows:

receiveFormChild=(value)=>{
  Console.log(value)
}
Render() {
  Return(
    <div>
      {this.state.num===2?"":<App1 num={this.state.num} popToFather={this.receiveFormChild}/>}
      <button onClick={this.addNum}>Click me +1</button>
    </div>
  )
}
When the child element runs popToFather, the message can be passed to the father!

Child element:

Render() {
  Return( [
      <p>{this.props.num}</p>,
      <button onClick={()=>this.props.receiveState("Consolation from child element")}>Child passer</button>
    ]
  )
}
The parent element successfully gets the condolences from the child elements!

This time, science is here.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.