Create by jsliang on 2019-3-18 08:37:10

Recently revised in 2019-3-22 11:46:54

If you think this is a good article, please send me astar, friendsstarIs my motivation to continue to update!Making the address


Hello guys, due to jsliang’s refactoring of the document library, some links in this article may be broken, and Jsliang lacks the energy to maintain the old articles on the Nuggets side. Sorry about that. If you need to get the latest article, please click on the GitHub address above and go to the document library to view the adjusted article.


  • React series source address

A directory

What’s the difference between a free front end and a salted fish

directory
A directory
The preface
Three main body
 3.1 Creating the React Project
 3.2 Project directory resolution
 3.3 Streamlining the project structure
 3.4 Components
 3.5 JSX
 3.6 Events and bidirectional data binding
 3.7 Optimization – Extracting the CSS
 3.8 Optimization – Extract JS
Four summarizes
V. References

The preface

Returns the directory

Get familiar with the React development process by writing a simple TodoList Demo.

Three main body

Returns the directory

Now, start the ball rolling.

3.1 Creating the React Project

Returns the directory

  1. Download the Node. Js
  2. Install React scaffolding:
    1. npm i create-react-app -g
  3. Start new projects:
    1. create-react-app todolist
    2. cd todolist
    3. npm start
  4. Open thelocalhost:3000To view the page

3.2 Project directory resolution

Returns the directory

Todolist + node_modules -- -- -- -- -- project rely on third-party packages - public -- -- -- -- -- -- -- -- Shared file - the favicon. Ico web TAB on the upper left corner, small icon - index. HTML -- Mainfest. json -- provides meta information to the project and is aligned with serviceworker.js, Offline APP definition -src ——————————————————— Main directory of the project -app.css -- Main component style -- app.js -- Main component entry -- app.test.js -- Automatic test file -- index.css - Global CSS file - index.js - entry for all code - logo.svg - dynamic diagram of the page - serviceworker.js - PWA Help to develop mobile APP applications, with caching function -.gitignore ——————————— configuration file. -package-lock. json ———— Lock the version number of the installation package to ensure that others use the same node package -package. json ————————— node package file when NPM I. Introduce the project and explain some dependency packages etc. - readme.md ———————————— project introduction fileCopy the code

3.3 Streamlining the project structure

Returns the directory

For ease of development, the initial directory of creat-react-app is simplified below:

Todolist + node_modules -- -- -- -- -- project rely on third-party packages - public -- -- -- -- -- -- -- -- Shared file - the favicon. Ico web TAB on the upper left corner, small icon - index. HTML - home page template - SRC -- -- -- -- -- -- -- -- -- - important directory - App. Js - the main component entry - index. Js - all code entry - gitignore -- -- -- -- --, the configuration file. - package.json ————————— node package file, introducing the project and some dependent packages, etc. - readme. md ———————————— project introduction fileCopy the code

Favicon. ico,.gitignore, readme. md are the ones we don’t need to worry about, but other files we need to simplify their code:

  1. index.html
Details of the code

       
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <title>Todolist</title>
  </head>
  <body>
    <noscript>You need to allow JavaScript to run in your APP</noscript>
    <div id="root"></div>
  </body>
</html>
Copy the code
  1. App.js
Details of the code
import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div className="App">
        Hello React!
      </div>); }}export default App;
Copy the code
  1. index.js
Details of the code
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
Copy the code
  1. package.json
Details of the code
{
  "name": "todolist"."version": "0.1.0 from"."private": true."dependencies": {
    "react": "^ 16.8.4"."react-dom": "^ 16.8.4"."react-scripts": "2.1.8"
  },
  "scripts": {
    "start": "react-scripts start"."build": "react-scripts build"."test": "react-scripts test"."eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    "0.2%" >."not dead"."not ie <= 11"."not op_mini all"]}Copy the code

3.4 Components

Returns the directory

Similar to the figure above, it’s easy for us to use paoding skills to divide the page and build the page part by part.

To give a more official term, it is called page componentization: cutting the page into several parts to facilitate the assembly of the page and maintenance of the code.

In the default configuration of create-react-app, app.js is a component.

App.js

// 1. Reference React and its components
import React, { Component } from 'react';

// 2. Define a Component called App that inherits from Component
class App extends Component {
  render() {
    return (
      <div className="App">
        Hello React!
      </div>); }}// 3. Export the App component based on the React instance
export default App;
Copy the code

Above, we reference, define, and export the App component, which we then use:

index.js

// 1. Introduce React and ReactDOM
import React from 'react';
import ReactDOM from 'react-dom';

// 2. Import app.js
import App from './App';

// 3. Use ReactDOM to render/mount app.js as a virtual DOM to the root node, which is in index.html
ReactDOM.render(<App />, document.getElementById('root'));
Copy the code

Index.js tells us that it will mount the app.js component to root via ReactDom. Where is the root node? Let’s take a look at index.html:

index.html


      
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortc ut icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
    <title>Todolist</title>
  </head>
  <body>
    <noscript>You need to allow JavaScript to run in your APP</noscript>
    <div id="root"></div>
  </body>
</html>
Copy the code

OK, this is easy: we define a root node in index. HTML, and then we render app.js as a component to index. HTML, and then we mount the node.

We know that the final combination of index.js and app. js is mounted on the node id=”root”, what if we open index2.js and app2. js and mount it on the node id=”root2″? Or do we open a node with id=”root3″ where we operate jQuery?

3.5 JSX

Returns the directory

In the create-react-app file, either in index.js:

ReactDOM.render(<App />, document.getElementById('root'));
Copy the code

Again in app.js:

class App extends React.Component {
  render() {
    return (
      <div className="App">
        Hello React!
      </div>); }}Copy the code

React is used to render the DOM using JSX.

import React from 'react';
Copy the code
  • JSX definition:

So, what is JSX?

One of the core mechanisms of React is the ability to create virtual DOM elements in memory. React leverages the virtual DOM to reduce manipulation of the real DOM to improve performance.

JSX is a combination of JavaScript and XML.

React invented JSX, which uses HTML syntax to create a virtual DOM. JSX treats < as HTML parsing and {as JavaScript parsing.

  • JSX usage:

In JSX syntax, if we need to use a component we created ourselves, we simply use its definition name, for example:

index.js

// 1. Introduce React and ReactDOM
import React from 'react';
import ReactDOM from 'react-dom';

// 2. Import app.js
import App from './App';

// 3. Use ReactDOM to render/mount app.js as a virtual DOM to the root node, which is in index.html
ReactDOM.render(<App />, document.getElementById('root'));
Copy the code

The third is custom component rendering to the root node.

Tip: In React, if you need to use a custom component, the component should not start with app in lower case. Instead, it should start with app in upper case.

3.6 Events and bidirectional data binding

Returns the directory

Here is our simplified directory structure:

Let’s modify the directory structure and start writing TodoList:

First, we change app.js to todolist.js:

App.js TodoList.js

import React, { Component } from 'react';

class TodoList extends Component {
  render() {
    return (
      <div className="TodoList">
        Hello React!
      </div>); }}export default TodoList;
Copy the code

Then we modify the component mounted to index.html in index.js to TodoList:

index.js

import React from 'react';
import ReactDOM from 'react-dom';

import TodoList from './TodoList';

// 3. Use ReactDOM to render/mount app.js as a virtual DOM to the root node, which is in index.html
ReactDOM.render(<TodoList />, document.getElementById('root'));
Copy the code

After modifying React, you can restart port 3000 to check whether React works.

In this step, we just change app.js to todolist.js, and make index.js mount todolist.js to root, and do nothing else.

Finally, if there is no problem, we write TodoList further, get the value of the input field, and render it into the list:

TodoList.js

Details of the code
// Fragment is a placeholder form, similar to Vue's Template
import React, { Component, Fragment } from 'react';

class TodoList extends Component {

  constructor(props) {
    super(props);
    this.state = {
      inputValue: ' '.list: []
    }
  }

  render() {
    return (
      <Fragment>
        <div>{/* Single data binding */}<input 
            type="text" 
            value={this.state.inputValue}
            onChange={this.handleInputChange.bind(this)}
          />
          <button>submit</button>
        </div>
        <ul>
          <li>
            <span>Have a meal</span>
            <span>X</span>
          </li>
          <li>
            <span>Go to bed</span>
            <span>X</span>
          </li>
          <li>
            <span>Play doug</span>
            <span>X</span>
          </li>
        </ul>
      </Fragment>
    )
  }

  handleInputChange(e) {
    console.log(e.target.value);
    this.setState({
      inputValue: e.target.value
    })
  }

}

export default TodoList;
Copy the code

Let’s start with the demo:

OK, so that when we enter a character, we can immediately get the corresponding data, this time to achieve one-way data flow: input field -> JS memory.

There are three points to note:

  1. FragmentReact is a placeholder provided by React that acts like<input>,<span>The same as the tag, but it does not appear in the actual rendering. The React JSX first layer must have tags, and then if used<div>And so on occupy a level, so, similar to VueTemplateReact is usedFragmentThis empty label.
  2. constructorRepresents the constructor of the parent class. In ES6, constructorconstructorEquivalent to its constructor, used to create a new parent classthisObject, andsuper(props)Is used to correctthisPointing to. In short, we can define data here and use it throughout the JS file.
  3. onChangeThis is the way React is specified, for exampleonClickEtc., in native JS, is usedonclickReact, however, requires semi-humped event names in order to differentiate. At the same time, bindhandleInputChange, can be directly inrenderLet’s write it.

References: What exactly are Constructor () and super() in React?

Now we have a basic understanding of React data and events. Click to add list events and click X to delete list events.

TodoList.js

Details of the code
// Fragment is a placeholder form, similar to Vue's Template
import React, { Component, Fragment } from 'react';

class TodoList extends Component {

  // constructor
  constructor(props) {
    super(props);
    // Define data
    this.state = {
      inputValue: ' '.list: []}}// Render the page
  render() {
    let closeStyle = {
      fontSize: '1.2 em'.color: 'deepskyblue'.marginLeft: '10px'
    }
    return (
      <Fragment>
        <div>{/* React time binding */} {/* React time binding */<input 
            type="text" 
            value={this.state.inputValue}
            onChange={this.handleInputChange.bind(this)}
          />
          <button onClick={this.handleBtnClick.bind(this)}>submit</button>
        </div>
        <ul>
          {
            this.state.list.map( (item, index) => {
              return <li key={index}>
                <span>{index}. {item}</span>
                <span style={closeStyle} onClick={this.handleItemDelete.bind(this, index)} >X</span>
              </li>})}</ul>
      </Fragment>HandleInputChange (e) {this.setState({inputValue: HandleBtnClick () {this.setState({list: [...this.state.list, this.state.inputValue], inputValue: HandleItemDelete (index) {const List = [...this.state.list]; list.splice(index, 1); this.setState({ list: list }) } } export default TodoList;Copy the code

In this part, we need to know three things:

  1. inrendercloseStyleThis is the variable that we use to define the CSS property that we pass throughstyle={closeStyle}, just write an in-line style (we’ll pull it out below)
  2. About the form of JSX traversal output:
{
  this.state.list.map( (item, index) = > {
    return <li key={index}>
      <span>{index}. {item}</span>
      <span style={closeStyle} onClick={this.handleItemDelete.bind(this, index)} >X</span>
    </li>})}Copy the code

We loop DOM nodes through {}. If you’ve learned jQuery, think of it as a concatenated string; If you’ve learned Vue, you can write it as v-for in a different way.

We don’t have to worry about why we wrote it that way, but let’s just accept the way we wrote it.

  1. About the changeconstructor, we used:
this.setState({
  list: list
})
Copy the code

In this form. Actually, there’s a mnemonic trick to this, because when we define data, we use:

// Define data
this.state = {
  inputValue: ' '.list: []}Copy the code

That is: this.state, so we need to modify the data, that is this.setState.

Now that our simple TodoList has been implemented, let’s further optimize and extract CSS and JS.

3.7 Optimization – Extracting the CSS

Returns the directory

In the above, we mentioned that closeStyle is an in-line notation that, as perfect programmers, we would certainly not tolerate, and we begin to pull away:

TodoList.js

import React, { Component, Fragment } from 'react'; import './style.css' // ... <ul> {this.state.list.map((item, index) => { return <li key={index}> <span>{index}. {item}</span> <span className="icon-close" onClick={this.handleItemDelete.bind(this, index)}>X</span> </li> }) } </ul>Copy the code

Here, we need to know: We can import the CSS file directly. Then, when naming the class, we need to use the className because React is afraid that the JS class will collide with the HTML class.

Finally, we will write the CSS file:

.icon-close {
  font-size: 1.2 em;
  color: deepskyblue;
  margin-left: 10px;
}
Copy the code

In this way, we have implemented the CSS extraction.

3.8 Optimization – Extract JS

Returns the directory

In chapter 4, the introduction to components, we explained that some complex JS can be extracted and embedded in the form of components where they need to be placed.

So, as we write more and more JSX, can we extract the rendering part of the list to simplify the JSX?

The answer is yes, let’s look at the implementation:

TodoList.js

Details of the code
// Fragment is a placeholder form, similar to Vue's Template
import React, { Component, Fragment } from 'react';

// Import components
import TodoItem from './TodoItem';

// Reference style
import './style.css';

class TodoList extends Component {

  // constructor
  constructor(props) {
    super(props);
    // Define data
    this.state = {
      inputValue: ' '.list: []}this.handleInputChange = this.handleInputChange.bind(this);
    this.handleBtnClick = this.handleBtnClick.bind(this);
    this.handleItemDelete = this.handleItemDelete.bind(this);
  }

  // Render the page
  render() {
    return<Fragment> <div> <label htmlFor="insertArea"> </label> {/* Single data binding */} {/* */} <input id="insertArea" type="text" value={this.state.inputValue} onChange={this.handleinputChange} /> <button onClick={this.handleBtnClick}> Submit </button> </div> <ul> { */} {this.getTodoitem ()} </ul> </Fragment>)} getTodoItem() {return this.state.list.map((item, index) => { return ( <TodoItem key={index} item={item} index={index} handleItemDelete={this.handleItemDelete} /> ) }) } HandleInputChange (e) {const value = e.target.value; this.setState( () => ({ inputValue: HandleBtnClick () {const list = this.state.list, inputValue = this.state.inputValue; this.setState( () => ({ list: [...list, inputValue], inputValue: "}))} // Method body - delete item handleItemDelete(index) {// immutable mutable list = [...this.state.list]; list.splice(index, 1); this.setState( () => ({ list: list })) } } export default TodoList;Copy the code

Let’s take a look at the changes todolist.js has made:

  1. We are inconstructor, the method is defined in advance:
this.handleInputChange = this.handleInputChange.bind(this);
Copy the code

That way, we don’t have to write.bind(this) down here.

  1. We modified itthis.setState()In the form of:

The original writing:

this.setState({
  list: list
})
Copy the code

Writing now:

this.setState( (a)= > ({
  list: list
}))
Copy the code

React 16 has been updated to make it easier to write this way than it was before. We’ll use it in the future.

  1. We refer to the component:
import TodoItem from './TodoItem';
Copy the code

And put the component in the body of the method: this.getTodoItem(), where this.getTodoItem() is defined:

// Get a single item
getTodoItem() {
 return this.state.list.map( (item, index) = > {
   return (
     <TodoItem 
       key={index}
       item={item} 
       index={index}
       handleItemDelete={this.handleItemDelete}
     />)})}Copy the code

Here we can see that we pass the data key, item, and index to the child TodoItem in the form of custom values. It also passes its own method to the child component via handleItemDelete, so that the component can call the parent component’s method:

TodoItem.js

Details of the code
import React, { Component } from 'react'

class TodoItem extends Component {

  constructor(props) {
    super(props);
    // This can save performance
    this.handleClick = this.handleClick.bind(this);
  }

  render() {
    const { item } = this.props;
    return (
      <li>
        <span>{item}</span>
        <span className="icon-close" onClick={this.handleClick}>X</span>
      </li>
    )
  }

  handleClick() {
    const { handleItemDelete, index } = this.props; handleItemDelete(index); }}export default TodoItem;
Copy the code

So we are done extracting the components and learning

  • The parent component passes values to the child component
  • A child component calls a parent component’s method

From this, we can write richer and more robust projects down the road.

React series source code address

Four summarizes

Returns the directory

Most of what we learn in any language is how to get started with “Hello World! Programming –

Then when doing small cases, we all like TodoList, because it can explain some basic knowledge points clearly.

Now, let’s review what we learned about React TodoList:

  1. Create-react-app installation and development
  2. The idea of componentization and its application in create-React-app.
  3. React Describes the definition and use of data and methods, and how to bind data in both directions.
  4. Divide large components into small components, and realize parent-child component communication (the parent component passes parameters to the child component, the child component calls the methods of the parent component)

Jsliang can write TodoList with jQuery, Vue and React.

V. References

Returns the directory

  1. React.component.react.purecomponent (React Performance Optimizations)
  2. Visual Studio Code + React
  3. React: What are constructor() and super()?

Jsliang advertising push: maybe partners want to know about the cloud server or partners want to buy a cloud server or partners need to renew the cloud server welcome to click on the cloud server promotion view!



Jsliang document library 由 Liang JunrongusingCreative Commons Attribution – Non-commercial Use – Same way Share 4.0 International LicenseGrant permission.

Based on theGithub.com/LiangJunron…On the creation of works.

Use rights other than those authorized by this License agreement may be obtained fromCreativecommons.org/licenses/by…Obtained.