All together

React is a JS library for building user interfaces that focus on views for componentized development

Componentized development is like a stack of wood, in which each component contains its own logic and style, and then comes together to create a complex page

The main characteristics of componentization are: combinable, reusable and maintainable

So without further ado, let’s dive right into today’s topic and get started by building a React project using the official recommended scaffolding

Create-react-app starts the React project

Step 1: Install the create-React-app scaffolding globally

npm i create-react-app -g
Copy the code

Step 2: Create the React project

Create-react-app Project name // Example: create-react-app react123Copy the code

React and react to the dom

Step 3: Enter the project and start the service

cd react123 && npm start
Copy the code

localhost:3000

Now, let’s go into the react project and see what the structure looks like.

Here is a show for you:

<! DOCTYPE html> <html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="# 000000">
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <title>React App</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
Copy the code

The SRC directory can also be deleted (except for the index.js main entry), which is similar to the default entry in WebPack4

Let’s start with JSX

In index.js under SRC, we can start the React tour. React uses Facebook’s JSX syntax, which is a combination of JAVASCRIPT and XML, directly into the code

// Install the react core package first. // Install the react core package first'react'; Import {render} from; import {render} from'react-dom'; // JSX syntax is escaped via Babel, escaped via the default babel-preth-react // JSX syntax is parsed into JS to be usedlet ele = (
    <h1 className="big">
        hi, <span>baby</span>
    </h1>
);
Copy the code

We can parse the JSX syntax directly on Babel’s website

// React.createElement("h1",
  { className: "big" },
  "hi, ",
  React.createElement(
    "span",
    null,
    "baby"));Copy the code

Create a virtual DOM with three parameters, type, props, and children, using React. CreateElement

  • Type: indicates the corresponding label H1
  • Props: Corresponding property {className: “big”}
  • Children: corresponding child node -> string ‘hi, ‘and a new react. createElement(“span”, null, “baby”)

The react. createElement object looks like this when it is printed

{
    type: 'h1', 
    props: {
        children: [
            'hi',
            {
                type: 'span',
                props: {
                    children: 'baby'
                }
            }
        ],
        className: 'big'}}Copy the code

After we have transformed the object, we can render such an object using the Render method provided by ReactDOM and render it to the page

The react. createElement block is the same syntax as the react. createElement block, which is the same as the react. createElement block.

So here we see a simple way to tease out the entire rendering order

JSX syntax -> createElement format -> Convert object -> Convert object to real DOM -> Render method

import React from 'react';  
import { render } from 'react-dom'; // react. createElement syntax sugarlet ele = (
    <h1 className="big"> hi, <span>baby</span> </h1> ); render(ele, window.root); // Render ele to rootCopy the code

Below is the rendering of the virtual DOM to the root node

When we wrote ele, we found that it was very similar to normal HTML, but I’m here to say that it’s not the same, so let’s see what the differences are.

The difference between JSX and HTML

  1. ClassName will be converted to class
  2. HtmlFor it’s going to convert to a for attribute label for
  3. JSX elements can be nested
  4. Adjacent React elements must be wrapped
  5. JSX can write JS, {} can write JS statements
  6. Only multi-line comments are supported, {/*… */}, but rarely with comments
  7. The style tag must be written as an object, such as {background: ‘skyblue’}

Having said these differences, directly open masturbation, no code more intuitive love, Hurry up go go go

import React from 'react';
import { render } from 'react-dom'; // Note: the number of the following comment marks corresponds to the number of the above distinctionlet singer = 'Jay Chou';
let style = { backgroundColor: '#0cc', color: '#fff', fontSize: '14px' };
let album = 'Across the ages';
let arr = ['sunny'.'cloudy'.'Rainy day'];

letEle = (/* 4. The react element must be wrapped (h1,label,input,p are all adjacent). The vue element must be wrapped with a template tag. / < react.Fragment> {/*1. After rendering it will change to <h1 class="song"> </h1>*/} <h1 className="song"> the fireworks easy cold - {/ * 3. The JSX elements can be nested * /} < span > {singer} < / span > < / h1 > {/ * 2. HtmlFor turns < labelfor="inp"></label> Clicking on the label tag automatically gets the input focus */} <label htmlFor="inp"> get focus </label> <inputtype="text" id="inp"/> < span style= "max-width: 100%; clear: both; min-height: 1em;'#fff'}} */}
        <p style={style}>{album}</p>
        {arr.map((item, index) =>{ 
            return <li key={index}>{item}</li>
        })}
    </React.Fragment>
);

render(ele, window.root);
Copy the code

component

React components are divided into two types: function components and class components. How do you distinguish between components? There’s a standard, capital letter

What? Yes, that’s right, lowercase is JSX element, ha ha, do not believe you look

Function component

import React from 'react';
import { render } from 'react-dom'; // This is a function componentfunction Song(props) {
    return (
        <div className="wrap"> < h1 > sunny - {props. Singer} < / h1 > < p > skip class for you of that day of, the day of the whispering < / p > < p > which one of the classroom, how do I see < / p > < / div >). // The render method does not render all the time, only render once (<Song singer=)"Jay Chou" />, window.root)
Copy the code

Of course, some people may not believe this, but if I write Song as Song and then render it, what’s the problem?

There’s no problem. That’s impossible, because react knows you and will give you an error telling you if you want to render with a React component. Capitalize the first letter

Officially, it’s fair trade, haha

Moving on to the function component, the function component is a thisless, life-cycle, stateless three-nothingness product. So you can imagine that it’s not used as often as a class component.

Here’s an example:

import React from 'react';
import { render } from 'react-dom'; // Function component Clockfunction Clock(props) {
    return <p>{props.date}</p>
}

setInterval(() => {
    render(<Clock date={new Date().toLocaleString()} />, window.root);
}, 1000);
Copy the code

It is possible to update the time in real time, but since the function component has no state and only renders once, it would be a bit silly to add a setInterval timer to the outer layer

More importantly, state changes are passed by us via properties. We have no state of our own, and we rely on passing when refreshing. This is bad

So we are going to ceremoniously invite the components of the big, class components shine

Class components

Again, let’s change it to a class component

Import react, {Component} from; import react, {Component} from'react';
import { render } from 'react-dom'; Class Clock extends Component {// Extends Componentconstructor() { super(); // Can be used after inheritancesetThis.state = {date: new date ().tolocaleString (), pos:'Beijing'}} // You need to provide a render method to return a DOM objectrender() {
        return<span style={{color: RGB (50, 50, 50); font-size: 14px! Important; white-space: normal;"'skyblue'}}>{this.state.pos}</span> </p> </React.Fragment> ); } // componentDidMount life cycle is called when the component is renderedcomponentDidMount() {
        setThis.setstate ({date: new date ().tolocaleString ()}); }, 1000); } } render(<Clock />, window.root);Copy the code

We did the same thing with the class component above, what else are we missing? Event? How can we write JS without adding events? Here’s how to add events

Then the above code, we continue to write, knock again, not afraid of tired, practice makes perfect, is a victory

import React, { Component } from 'react';
import ReactDOM, { render } from 'react-dom';

class Clock extends Component {
    constructor() {
        super();
        this.state = { date: new Date().toLocaleString(), pos: 'Beijing'}; HandleClick = this.handleclick.bind (this); } /* There are several ways to bind methods that might use this 1. 2. Bind bind this. Handleclick. bind(this) 3. 4.ES7 syntax resolves this to refer to handleClick = () => {}. */ handleClick = () => {console.log(this) => {console.log(this); Us to remove this component / / remove components. We use the method of the ReactDOM ReactDOM unmountComponentAtNode (window. Root); }render() {// attach a click event to it, using the hump syntax onClick={}return(< react. Fragment> <p onClick={this.handleClick}> </p> <p>'skyblue'}}>{this.state.pos}</span>
            </p>
        </React.Fragment>)
    }
    componentDidMount() {
        this.timer = setInterval(() => {
            this.setState({ date: new Date().toLocaleString() });
        }, 1000);
    }
    componentWillUnmount() {
        clearInterval(this.timer);
    }
}

render(<Clock />, window.root);
Copy the code

After executing the code above, clicking the p tag at the current time removes the component (DOM) from the root node, but there are some common problems that you might miss

  • When the component is removed, the timer is still running and the setState is still updating the date state, so an error will be reported
  • Let’s focus on explaining this problem
Class Clock extends Component {//componentDidMount() {// As usual, we attach the timer directly to this instance this.timer =setInterval(() => { this.setState({date: new Date().toLocaleString()}) }); } // This lifecycle is called when the component is about to be unloadedcomponentWillUnmount() {// Remove the timer and bind method clearInterval(this.timer); }}Copy the code

Well, the above error problem is solved. However, better said than sung, why put timer on this? Can’t we put the timer state in this.state?

This. State indicates that the current page depends on this state. When the state changes, the view can be refreshed, and setState can update the page

However, placing the timer directly on the current instance (this) does not affect the page even if it is deleted (emptied)

So much for components, let’s make a summary

  • The component has two data sources
    • One is external to the property
    • One is owned by the state itself

The React state is very important. When the react state changes, you can refresh the view and change it. So let’s talk about state alone

State of the state

Pale text, as real code to see the exciting, on the code

Import React, {Component} from'react';
import { render } from 'react-dom';

class Counter extends Component {
    constructor() { super(); this.state = { count: 1 }; } handleClick = () => {this.setState({count: this.state.count + 1}); // this.setState(prevState => ({count: prevstate.count + 1})); // this.setState(prevState => ({count: prevstate.count + 1})); this.setState(prevState => ({ count: prevState.count + 1 })); this.setState(prevState => ({ count: prevState.count + 1 })); }render() {
        return</span> {this.state.count} <button onClick={this.handleclick}> </div>; } } render(<Counter></Counter>, window.root);Copy the code

State has a feature: can multiple states be batch updated? So if I write three this.setState to change the count, it should change the state three times

React doesn’t do this. It would be crazy to refresh the page every time the state changes. React remembers the state (count) first and then refreshes the page at the end

The setState set above is then used to preserve the state of count and then change it once more. In plain English, if the next update depends on the last update, you have to write it as a function

Okay, let’s talk about communication between components. Let’s talk about direct communication between parent and child components

Communication between components

Communication between components, parent-child components are passed through properties, parent -> child -> grandchild

One way data stream, data direction is one way, child can’t change the parent’s property so let’s do a little demo

The parent component songs. Js


import React, { Component } from 'react';
import { render } from 'react-dom';
import axios from 'axios'; // axios is used to request import List from'./list'; // Subcomponent import Audio from'./audio'; // Subcomponent import'./css/songs.css';

class Songs extends Component {
    constructor() {
        super();
        this.state = { songs: [], mp3Url: ' ', isPlay: false}; } // Child to parent communication -> parent provides a method, ChooseSong = (url, SetState ({mp3Url: url, isPlay}) => {// Where the child component returned a property that changed the state of isPlay // where the parent component Audio of the List changed the value of the property this.setState({mp3Url: url, isPlay}); }render() {
        return (
            <div className="songs-box"> <ul> {this.state.songs. Map ((item, index) => (/*); item} choose={this.chooseSong}></List> ))} </ul> <Audio url={this.state.mp3Url} played={this.state.isPlay}></Audio> </div> ); } asynccomponentDidMount() {// Send ajax requests in React now we use axios // axios to encapsulate RESTFul promise based jSONP available on the server sidelet { data } = await axios.get(Jj Lin 'http://musicapi.leanapp.cn/search?keywords=');
        this.setState({ songs: data.result.songs });
    }
}

render(<Songs></Songs>, window.root);
Copy the code

Unplayed effect

Post an address

As you can see from the small demo above, there are three main ways to communicate between components

  • The first way is through attribute passing, parent -> child -> grandchild.
    • One – way data flow, data direction is one – way, child cannot change the parent’s attributes
  • The second way is if the father writes a method and passes it on to the son.
    • The son calls this method, in which the state can be changed
  • The third way is peer component passing
    • Sibling components that want to pass data can find a common parent and create a parent without a parent

Controlled components and uncontrolled components

Next, look at the concepts of controlled and uncontrolled components, which refer to form elements

Now that form elements are involved, it’s time for the bidirectional data binding we’re looking forward to

Two-way data binding

import React, { Component } from 'react';
import { render } from 'react-dom';

class Input extends Component{
    constructor(){
        super();
        this.state = {val: 'hello'}; } handleChange = (e) =>{//e is the event sourcelet val = e.target.value;
        this.setState({val});
    };
    render() {return (<div>
            <input type="text" value={this.state.val} onChange={this.handleChange}/>
            {this.state.val}
        </div>)
    }
}
render(<Input />, window.root);
Copy the code

Two-way data binding is implemented by listening to the onChange event, and then changing the state of the new input value to the value attribute of the input

The controlled components

State-controlled components must have the onChange method or they cannot be used

Controlled components can be assigned default values

import React, { Component } from 'react';
import { render } from 'react-dom';

class App extends Component{
    constructor(){
        super();
        this.state = {a: 'to break the wind', b: 'fighting'}; HandleChange = (e) => {handleChange = (e) => {handleChange = (e) => {handleChange = (e) =>let name = e.target.name;
        this.setState({ [name]: e.target.value });
    }
    render() {return (
            <form>
                 <input type="text"
                    required={true}
                    value={this.state.a}
                    onChange={this.handleChange}
                    name="a"
                />
                <input type="text"
                    required={true}
                    value={this.state.b}
                    onChange={this.handleChange}
                    name="b"
                />
                <input type="submit" />
                <p>{this.state.a}</p>
                <p>{this.state.b}</p>
            </form>
        )
    }
}

render(<App></App>, window.root);
Copy the code

Uncontrolled component

The so-called uncontrolled components have three characteristics:

  1. You can manipulate the DOM to get the real DOM
  2. Can be combined with third-party libraries
  3. No validation of the current input is required, and no default values are required
import React, { Component } from 'react';
import { render } from 'react-dom'; Ref // 2.React.createRef() v16.3+ class App extends Component {constructor() {
        super();
        this.aaa = React.createRef();
    }
    componentDidMount() { // this.aaa.focus(); This.aaa.current. Focus (); // corresponding to 2}render() {
        return (<div>
            {/* 1.<input type="text"ref={input=>this.aaa = input} />*/} {/* 2. This will automatically place the current input field in this.aaa.current */} <inputtype="text" ref={this.aaa} />
        </div>)
    }
}
render(<App />, window.root);
Copy the code

As soon as you enter the page, it will automatically get the focus of the input box, and then you can try to click to see

It’s late. The program is just right

React has a lot more to say, though, and it doesn’t cover anything like the life cycle

However, rest assured, the coming will come, one can not be less, in the following article, I will continue to learn and share

So that’s all for today, thank you for taking the trouble to watch, everybody, all right!!