preface

Some nonsense and personal perception, see dry goods directly skip…. To the JSX

I’ve been writing on and off for half a year now. It’s basically a stack of personal skills and answers to interview questions. Interested partners can click on my home page to see.

Talk about today’s main character -React. The React source code is something I’ve always wanted to read and read, but I often feel sleepy. Then I started to get lazy and started reading around things like react-Router, react-redux, etc. I used to write articles after I read them. Now I want to read it while I write it, so let’s look at it another way. If there is something wrong, welcome to discuss, if you think it is ok, you can click a like, thank you!

As a heavy user and fan of React. I will be with you from “user” to “understanding” progress!

React information

Utilitarian perspective

Open recruitment software, now basically large factories, and even outsourcing companies are generally required to know React or Vue. The salary is also very attractive.

(Picture is from Boss.)

In order to make a fortune this simple dream should also study.

Perspective of Learning

Angular, React, and Vue dominate the front end. React and Vue are preferred in China. Therefore, learn React from the perspective of learning.

www.npmtrends.com/react-vs-vu…

Why learn source code

I’ve asked this question before. Almost all interviews are about building rockets and turning the screws.

I think there are two ways to look at it:

  1. The applicant
    1. Read andReactIn the case of solving the problem, the ceiling must be raised
    2. An excellent framework is an excellent teacher
  2. Employer, since everyone can do the job, I’ll find someone who knows more about it

JSX

Without further ado, let’s get to it.

React JSX JSX JSX JSX JSX JSX JSX JSX JSX I’ll give you a demo to help you answer it.

import React from "react"; import ReactDOM from "react-dom"; Class App extends React.Component {render() {const text = "ha ha" return (<div> <p>{text}</p> </div>); } } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);Copy the code

Let me ask you a few questions first. If you can answer them clearly and quickly, congratulations, you have a solid foundation. If not, take a look together, and then you can write your answers in the comments section for discussion.

  • What is theJSX?JSXandJSWhat does it matter?
  • JSXWhat is the underlying principle of?
  • whyReactWant to chooseJSX?

Take the question with you.

What is the JSX

Here’s a quote from React.

const element = <h1>Hello, world! </h1>;Copy the code

It’s called JSX, and it’s a syntax extension to JavaScript.

Syntactic extensions, which means that JS has everything it has, and some other functionality. Obviously, I haven’t seen him in JavaScript learning. Can it run in JavaScript? Open the Chrome Console.

The syntax errors are all over the place. It seems that this part is an extra function. How does that work?

{
        test: /\.(js|jsx)? $/.// Enable caching
        options: { cacheDirectory: true },
        loader: 'babel-loader',},Copy the code

It tells WebPack that we need to use Babel to parse JSX code. Ok, that is, to run JSX, you must parse with Babel. Okay, what is Babel?

babel

Play a quote from Babel’s website

Babel is a JavaScript compiler

Babel is a toolchain for converting ECMAScript 2015+ version code into backwardly compatible JavaScript syntax so it can run in current and older versions of browsers or other environments.

Babel, in fact, helps us parse the code that we write and make it look like a browser. JSX, for example, and fresh ES6 syntax can run on older browsers and be understood by older browsers.

Which begs the question, what has Babel turned JSX into?

Online conversion: babeljs. IO /repl

You can throw that little demo up there.

No. The thing we return out becomes react.createElement. Lol, that’s why we didn’t even use React. JSX will eventually be converted to react. createElement, which will be used! The latest one, however, does not need to be quoted and will not report any errors, as it identifies itself.

Website: zh-hans.reactjs.org/blog/2020/0…

// Imported by the compiler (forbid self-imported!) import {jsx as _jsx} from 'react/jsx-runtime'; function App() { return _jsx('h1', { children: 'Hello world' }); }Copy the code

Note that the source code does not need to introduce React to use JSX! (You still need to introduce React, though, in order to use the hooks or other exports that React provides.)

Let’s go back to what we mentioned earlier on React

It’s called JSX, and it’s a syntax extension to JavaScript.

React.createElement () {react. createElement () {react. createElement ();

createElement

React (JSX); react (JSX); react (JSX);

export function createElement(type, config, children) {
  // The propName variable is used to store element attributes that need to be used later
  let propName; 
  // props is the set of key-value pairs used to store element attributes
  const props = {}; 
  // Key, ref, self, source are all attributes of the React element
  let key = null;
  let ref = null; 
  let self = null; 
  let source = null; 

  The config object stores the attributes of the element
  if(config ! =null) { 
    // The first thing you do is assign the ref, key, self, and source attributes in order
    if (hasValidRef(config)) {
      ref = config.ref;
    }
    // String the key here
    if (hasValidKey(config)) {
      key = ' ' + config.key; 
    }
    self = config.__self === undefined ? null : config.__self;
    source = config.__source === undefined ? null : config.__source;
    // Move all the properties in config to props one by one
    for (propName in config) {
      if (
        // Filter out properties that can be pushed into the props objecthasOwnProperty.call(config, propName) && ! RESERVED_PROPS.hasOwnProperty(propName) ) { props[propName] = config[propName]; }}}// childrenLength is the number of children of the current element; the 2 subtracted is the length of the type and config parameters
  const childrenLength = arguments.length - 2; 
  // If type and config are omitted, there is only one argument left, which generally means that the text node is present
  if (childrenLength === 1) { 
    // assign this parameter directly to props. Children
    props.children = children; 
    // Handle nested child elements
  } else if (childrenLength > 1) { 
    // Declare an array of children
    const childArray = Array(childrenLength); 
    // Push the child element into the array
    for (let i = 0; i < childrenLength; i++) { 
      childArray[i] = arguments[i + 2];
    }
    // Finally, assign this array to props. Children
    props.children = childArray; 
  } 

  / / defaultProps processing
  if (type && type.defaultProps) {
    const defaultProps = type.defaultProps;
    for (propName in defaultProps) { 
      if (props[propName] === undefined) { props[propName] = defaultProps[propName]; }}}// Finally returns a call to ReactElement execution method, passing in the arguments just processed
  return ReactElement(
    type,
    key,
    ref,
    self,
    source,
    ReactCurrentOwner.current,
    props,
  );
}
Copy the code

Instead of looking at the parameters, let’s look at the name of the return value and the name of the function. Our initial guess is that JSX creates a React element using createElement, which is then rendered to the element we named by reactdom.render.

Ok, so the JSX elements we normally write are the ones generated by ReactElement. Let’s see what ReactElement generates.

Let’s print out JSX that we usually write.

Intuitively, does it feel like this is a virtual DOM node, and it has a type and then a DIV, and the corresponding div tag is an HTML div tag? And then there’s className, which obviously corresponds to the class. Let’s go and have a look.

ReactElement

const ReactElement = function(type, key, ref, self, source, owner, props) {
  const element = {
    // This is the React node identifier
    $$typeof: REACT_ELEMENT_TYPE,

    // This is clearly the corresponding HTML tag
    type: type,
    key: key,
    ref: ref,
    props: props,

    // Who created the record? Dig a hole
    _owner: owner,
  };

  // The configuration of the development environment, mainly Object. Freeze, can be found in the MDN. I don't want to go into that
  if (__DEV__) {
    // The validation flag is currently mutative. We put it on
    // an external backing store so that we can freeze the whole object.
    // This can be replaced with a WeakMap once they are implemented in
    // commonly used development environments.
    element._store = {};

    // To make comparing ReactElements easier for testing purposes, we make
    // the validation flag non-enumerable (where possible, which should
    // include every environment we run tests in), so the test framework
    // ignores it.
    Object.defineProperty(element._store, 'validated', {
      configurable: false.enumerable: false.writable: true.value: false});// self and source are DEV only properties.
    Object.defineProperty(element, '_self', {
      configurable: false.enumerable: false.writable: false.value: self,
    });
    // Two elements created in two different places should be considered
    // equal for testing purposes and therefore we hide it from enumeration.
    Object.defineProperty(element, '_source', {
      configurable: false.enumerable: false.writable: false.value: source,
    });
    if (Object.freeze) {
      Object.freeze(element.props);
      Object.freeze(element); }}return element;
};
Copy the code

$$typeof is the React node. Then there are the normal parameters, such as key, ref, props, and so on.

ReactDOM.render

This is how the React node renders as a real node. No more words, on the source code!

export function isValidContainer(node: mixed) :boolean {
  return!!!!! ( node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE  || (node.nodeType === COMMENT_NODE && (node: any).nodeValue ===' react-mount-point-unstable '))); }export function render(
  element: React$Element<any>,
  container: Container,
  callback: ?Function.) {
  // The container can be found
  invariant(
    isValidContainer(container),
    'Target container is not a DOM element.',);if (__DEV__) {
    const isModernRoot =
      isContainerMarkedAsRoot(container) &&
      container._reactRootContainer === undefined;
    if (isModernRoot) {
      console.error(
        'You are calling ReactDOM.render() on a container that was previously ' +
          'passed to ReactDOM.createRoot(). This is not supported. ' +
          'Did you mean to call root.render(element)? ',); }}// There is something about fiber architecture that I want to talk about later
  return legacyRenderSubtreeIntoContainer(
    null,
    element,
    container,
    false,
    callback,
  );
}
Copy the code

Does it feel easy to remove the __DEV__ case? Return the result of a function…

ReactDOM.hydrate

This function I find interesting is only one line different from reactdom.render

legacyRenderSubtreeIntoContainer(
    null,
    element,
    container,
- false,
+ true,
    callback,
  );
Copy the code

First, this hydrate means water hydrate. Add water and color to a knot. It was used to add click events and so on in SSR process. ReactDOM.Render will be phased out after React17 and replaced entirely with ReactDOM. Hydrate

React

The reactdom.render () method of manipulating server render containers for hydrate is deprecated and will be removed in React 17. Instead, use hydrate().

Why use JSX

So here’s a little tip for solving this problem. Why to XX is actually to ask you, the benefits of XX. Ok, that’s an easy answer

First, because without JSX, we would have hundreds of React. Crearteelements in our code.

Second, this syntactic sugar allows developers to create virtual DOM using familiar HTML tags, reducing learning costs. Improve development efficiency and experience

The rest of the pit

  • LegacyRenderSubtreeIntoContainer (relating to the fiber structure
  • _owner (What does this property do when it is created

Everyone like, trouble like ah!! Any questions can also be pointed out in the comments section

The index

zh-hans.reactjs.org/docs

www.babeljs.cn/docs/