React is easy to learn compared to Vue and Angular. Here are some notes on how to learn React:

JSX grammar

This is a great syntax for using JAVASCRIPT to express HTML. It is a syntactic sugar, but it is sweet enough to know that JSX will eventually be escaped by Babel into standard JS syntax, for example:

const title = <h1 className="title">Hello, world!</h1>;
Copy the code

Open the Babel REPL and type in the code above to find that it ends up like this:

const title = React.createElement(
    'h1'./ / tag name
    { className: 'title' }, // Attribute object
    'Hello, world! ' / / child elements
);
Copy the code

At this point, you should have a sense of the structure, but to make sense of it, let’s do a more complicated example:

const element = (
  <div className="title" width="200" height="100">
    hello<span className="content">world!</span>
  </div>
)
Copy the code

Is converted to:

const element = React.createElement(
  "div"./ / tag name
  { // Attribute object
    className: "title".width: "200".height: "100",},"hello".// The first child
  React.createElement( // The second child
    "span",
    { className: "content" },
    "world!"));Copy the code

It can be seen that JSX is very strong expressive, concise syntax, is a big killer of the front end.

Virtual DOM

We already know that JSX fragments are translated into code wrapped in the react. createElement method. What exactly is the react. createElement method? It’s as simple as converting a parameter to an object:

function createElement(type, attrs, ... children) {
  return { type, props: { attrs, children } }
}
Copy the code
  • The first argument is the label name of the DOM node, which can be div, H1, SPAN, and so on
  • The second argument is an object that contains all the attributes of the node, possibly including className, ID, and so on
  • Start with the third argument, which is its child node

So JSX will eventually be converted to objects with this structure, which is also called the virtual DOM!

const title = <h1 className="title">Hello, world!</h1>;
Copy the code

In essence:

{
  type: 'h1'.props: { attrs: { className: 'title' }, children: [ 'Hello, world! ']}}Copy the code

When there is only one child node, children is usually not written as an array. Instead, the first element of the array is taken:

{
  type: 'h1'.props: { attrs: { className: 'title' }, children: 'Hello, world! '}}Copy the code

So our React. CreateElement method can be modified slightly:

function createElement(type, attrs, children) {
  return {
    type,
    props: {
      attrs,
      children: arguments.length > 3 ? Array.prototype.slice.call(arguments.2) : children,
    },
  }
}
Copy the code

Function component

The function component is a function that takes a property object and returns a React element. Such as:

function Title(props) {
  return <h1 className="title">The title</h1>
}
Copy the code

This definition is pretty clear, but note that the following functions are also function components:

function MyTitle(props) {
  return <Title />
}
Copy the code

Because the

syntax is equivalent to executing the Title function, you still get a React element.

Class components

The class component is a react.componentsubclass that implements the Render method.

class TitleComponent extends React.Component {
  render() {
    return <h1 className="title">The title</h1>}}Copy the code

What does a React.Component parent look like, you might ask, if you look at TypeScript type declarations:

class Component<P.S> {
  readonly props: Readonly<P> ;
  state: Readonly<S>;

  constructor(props: Readonly<P> | P);
  setState<K extends keyof S>(
    state: ((prevState: Readonly<S>, props: Readonly<P>) = > (Pick<S, K> | S | null)) | (Pick<S, K> | S | null), callback? :() = > void) :void; forceUpdate(callback? :() = > void) :void;
  render(): ReactNode;
}
Copy the code

The React.Component parent class has the following structure:

class Component {
  constructor(props) {
    this.props = props
    this.state = {}
  }

	// Status update
  setState(nextState, callback) {
    // ...
  }

  // Force refresh
  forceUpdate() {
    // ...
  }

  render() {
    throw new Error('This method is abstract and requires subclass implementation')}}Copy the code

component

Components are divided into built-in native components and custom components:

  • The built-in components are legal HTML tags such as div and SPAN, whose type in the virtual DOM is a string
  • A custom component is a function or class component whose type in the virtual DOM is no longer a string but a function

Render method

The render method converts the virtual DOM into a real DOM and inserts it into the container. The function structure is:

function render(vdom, container) {
  // ...
}
Copy the code

The syntax is as follows:

ReactDOM.render(
    <h1>Hello, world!</h1>.document.getElementById('root'));Copy the code

What is the dark magic inside the Render function that maps the virtual DOM to the real DOM? Remember the data structure of the virtual DOM?

{ type: 'xxx'.props: { attrs: {}, children: []}}Copy the code

It’s actually quite simple, with just a few lines of code:

function render(vdom, container) {
  if (typeof vdom === 'string') { // When vDOM is a string, the render result is a text
    return container.appendChild(document.createTextNode(vdom))
  }
  const {type, props: {attrs = {}, children}} = vdom
  const dom = document.createElement(type)
  Object.keys(attrs).forEach(key= > {
    const value = attrs[key]
    if (key === 'style') {
      for (let attr in value) dom.style[attr] = value[attr]
    } else {
      dom[key.startsWith('on')? key.toLocaleLowerCase() : key] = value } }); [].concat(children).forEach(child= > render(child, dom)) // Recursively render child nodes
  return container.appendChild(dom) // Mount the render results to the real DOM
}
Copy the code

The life cycle

The life cycle is divided into the old version and the new version, each with a diagram to describe, the old version declaration cycle is as follows:

ComponentWillUnmount (); / / Will (); / / Will (); / / Will (); / / Will ();

  • componentWillMount

  • componentWillReceiveProps

  • componentWillUpdate

Added:

  • GetDerivedStateFromProps Static method

  • GetSnapshotBeforeUpdate instance method

Here is a schematic of the new declaration cycle: