1. Introduction
1.1 Learning Background
The author uses Vue as his technical stack and has nothing to do in his spare time. I would like to review the basic course of React and record my own learning process of React, hoping to help beginners like me. Here is the link of The course of React: React16 free video tutorial (28 episodes in total).
1.2 introduction of the React
Currently, the most popular front-end framework in the world is launched and maintained by Facebook with a strong community. Most of the first and second tier Internet companies in China use React for development, and some useful frameworks such as ReactNative and React VR have been derived.
React development environment (React 17)
2.1 the Node. Js installed
Go to nodeChinese: nodejs.cn/ and install the stable version. After installing the stable version, use win+R to open CMD and enter the code
node -v
Copy the code
If the correct version number is displayed, the Node is successfully installed. Then check the NPM status
npm -v
Copy the code
If the correct version number appears, NPM is fine
2.2 React Scaffolding Installation
As a beginner, use create-React-app, the official scaffolding tool recommended for installation, to reduce potholes
npm install -g create-react-app
Copy the code
2.3 Creating a React Project
After the scaffolding is installed, create a ReactDemo folder on drive D, then go to the folder and create the React project
D: // create ReactDemo folder creation-react-app myreact // create ReactDemo folder creation-react-app myreact // create ReactDemo folder creation-react-app myreact // create ReactDemo folder creation-react-app myreact // Enter the project directory NPM start // preview the project. If the project can be opened normally, it indicates that the project is created successfullyCopy the code
3. Introduction of scaffold generation project directory
/ / table of contents├─public │ ├─ favicon. Ico │ index.html │ manifest.json │ robots. TXT │ ├─ SRC app.css app.js App.test.js index.css index.js logo.svg reportWebvitals.js setuptests.js │ gitignore │ package-lock.json │ package.json │ README, mdCopy the code
3.1 Project root directory file
- Public: a public file that stores public templates and ICONS.
- SRC: Stores the main project code as well as some project static resources, encapsulated apis, and so on.
- gitignoreThis is git’s optional upload configuration file, usually scaffolding is already configured with some files that do not need to be uploaded, such as
node_modules
,build
And so on. - package-lock.jsonThis file locks the version number at the time of installation, and needs to be uploaded to Git to ensure that others will not use git again
npm install
When everyone’s dependence can ensure consistency. - package.json: This file is
webpack
Configuration and project package management file, usually NPM installed some package version will be recorded in it, whichdependencies
The packages inside are the ones that will continue to be used after the project goes live,devDependencies
The package inside is used by the development environment, online will not be used. - README.md: This file is mainly used to record the contents of the project, mainly used
Markdown
Syntax to write
3.2 Public Folder
- Favicon. ico: This is the TAB icon of the project in the browser, usually displayed in the upper left corner of the browser TAB.
- index.htmlThe react code we wrote is embedded in the template file on the first page
body
The followingrootdiv
The inside. - Mainifest. Json: mobile configuration file.
3.3 SRC Folder
- Index.js: entry file for the project
- app.jsThe scaffolding is configured for us as the first module
npm run start
Then open the web page to see the first page - Serviceworker.js: This file is used to write mobile applications. PWA must use this file, which is equivalent to offline browsing.
3.4 Processing before writing code
Ico and index.html file. Delete the rest. Delete this line of code inside index.html
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
Copy the code
SRC folder only app.js and index.js, inside the code processing is as follows
//App.js
function App() {
return <div>Initialize the</div>;
}
export default App;
Copy the code
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>.document.getElementById('root'));Copy the code
Then open the page and see only the white background text initialization means that our project is initialized.
4. HelloWorld
4.1 app. Js code
import React, { Component } from 'react';
class App extends Component {
render() {
return <div>Hellow World</div>; }}export default App;
Copy the code
The first step here is to introduce the Component from the React core library
import React, { Component } from 'react';
Copy the code
This is ES6’s deconstruction assignment method
import React from 'react';
const Component = React.Component;
Copy the code
4.2 JSX grammar
JSX is a combination of Javascript and XML. React invented JSX, which makes it easy to create a virtual DOM using HTML syntax. When encountered with <, JSX interprets it as HTML and when encountered with {it interprets it as JavaScript.
// JSX syntax compared to normal JS syntax
//jsx
<ul className="my-list">
<li>JSPang.com</li>
<li>I love React</li>
</ul>;
// Plain JS syntax
var child1 = React.createElement('li'.null.'JSPang.com');
var child2 = React.createElement('li'.null.'I love React');
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);
Copy the code
As can be seen from the above comparison, there is no difference between using JSX syntax in JS and writing in HTML at ordinary times, while writing HTML structure code in JS with ordinary JS syntax is complicated, the appearance of JSX greatly reduces our code quantity
Another advantage of JSX syntax is that variables can be enclosed in {} and rendered in a page, for example
class App extends Component {
render() {
const num = 10;
return (
<ul className="my-list">
<li>{num}</li>// The ternary operator can also be used within {}<li>{false ? 'Red' : 'blue '}</li>
</ul>); }}Copy the code
4.3 VSCode configuration
Using JSX syntax in js does not recognize and generate labels quickly. If you also use VSCode, you can add this line of code to your Settings
"emmet.includeLanguages": {
// JSX code prompt
"javascript": "javascriptreact"
},
Copy the code
5. React Instance – Little Sister Service menu
5.1 Creating the Little Sister Component
In the SRC folder, create a new folder called Xiaojiejie. Inside the folder, create an index.js file and write a basic structure
import React, { Component } from 'react';
class Xiaojiejie extends Component {
render() {
return (
<div>
<div>
<input type="text" />
<button>Increase the service</button>
</div>
<ul>
<li>The head massage</li>
<li>Essential oil TuiBei</li>
</ul>
</div>); }}export default Xiaojiejie;
Copy the code
After building the basic structure, we went to app.js to introduce the little sister component
import React, { Component, Fragment } from 'react';
//import imports the little sister component. Note that the component name and use must be uppercase
import Xiaojiejie from './Xiaojiejie';
class App extends Component {
render() {
return (
<Fragment>
<div>Hello World</div>{/* Use the little sister component */}<Xiaojiejie />
</Fragment>); }}export default App;
Copy the code
After introducing the little sister component, we will open the page to see if the structure is displayed, which means that this step is successful.
5.2 Rules for Component Wrapping &Fragment tag & Comments in JSX
-
The Fragment rule: This is a very important rule. For example, in the code above, we will get an error if we remove the outer
. React requires that a component be wrapped at the outer layer.
// The outermost tag is missing. Only one tag can exist in the outermost tag of the return class App extends Component { render() { return ( <div>Hello World</div> {/* Use the little sister component */} <Xiaojiejie /> ); }}Copy the code
-
Fragment tags: Most of the time you can solve component wrapping problems by adding a div to the top layer, but sometimes, like flex layout, if you have a div wrapped around the top layer, the inside will not work. In this case, use the Fragment tag, which wraps the tag without showing it on the page.
// Need to be introduced before use import React, { Component, Fragment } from 'react'; Copy the code
-
JSX internal comments: Normal JS comments only need //, but in JSX, you need to wrap the comments with {/**/}, or you can use the editor’s CTRL +/ shortcut comment
6. Add features to the Little Sister service
6.1 Reactive Data Binding
React uses the virtual DOM, so it is not recommended to operate DOM elements directly. Therefore, try to use data-driven methods to do so. React will update DOM based on data changes.
We first need to bind the values to the input and implement data responsiveness. We define the data first
class Xiaojiejie extends Component {
// Use the constructor
constructor() {
super(a)// Call the parent constructor, fixed
this.state = {
/** New service content */
serviceValue: ' './** Service list */
serviceList: []}}... }Copy the code
After defining the data, bind it to the input
// Use {} to store variables
<input value={this.state.serviceValue} type="text" />
Copy the code
After doing this, we can change the value of serviceValue from constructor and see that the input field on the page is already displaying the data properly. One problem is that the input field does not change.
This is caused by forcing the binding of value. To change the value we need to unbind the response event and dynamically change the value of serviceValue
/ / dom code
<input value={this.state.serviceValue} onChange={this.serviceChange} type='text' />
// Create a serviceChange event
class Xiaojiejie extends Component {
constructor(){... }render() {
return (
...
);
}
// Create a serviceChange event, the same as render
serviceChange = (e) = > {
console.log(e.target.value);
this.state.inputValue=e.target.value
}
}
Copy the code
After the event is created and bound, we will go to the browser and try to enter the value in the input field. We will find that the debugger reported an error because the data in the state field cannot be changed directly. Instead, we will use setState() to change the value
/ / dom code
<input value={this.state.serviceValue} onChange={this.serviceChange} type='text' />
// Create a serviceChange event
class Xiaojiejie extends Component {
constructor(){... }render() {
return (
...
);
}
// Create a serviceChange event, the same as render
serviceChange = (e) = > {
console.log(e.target.value);
this.setState({
serviceValue:e.target.value
})
}
}
Copy the code
Now that you can see the correct result on the console, there are three ways to write React events and bindings
6.2 Three Methods for Creating events and Binding
// The first way is to change the direction of this by using bind, otherwise an error will be reported
<input value={this.state.serviceValue} onChange={this.serviceChange.bind(this)} type='text' />
serviceChange(e){
this.setState({
serviceValue:e.target.value
})
}
// The second way, I prefer to use
<input value={this.state.serviceValue} onChange={this.serviceChange} type='text' />
// By using the arrow function when creating the method, the this keyword points to this at the position defined by the arrow function.
serviceChange = (e) = > {
this.setState({
serviceValue:e.target.value
})
}
// The third way of doing this is by changing the direction of this from constructor
constructor(props){
super(props)
this.serviceChange=this.serviceChange.bind(this)}render() {
return (
<input value={this.state.serviceValue} onChange={this.serviceChange} type='text' />
);
}
serviceChange(){
console.log(this.props.index)
}
Copy the code
6.3 Adding Service Functions
After the data responsive binding, we can start to implement the add service function. First we need to rewrite the contents of
-
into the data rendering structure
<ul>
{this.state.serviceList.map((item, index) = > {
React generates an error when a key is missing
return <li key={index}>{item}</li>;
})}
</ul>
Copy the code
Bind click events to buttons
<button onClick={this.addservice}> addService </button>Copy the code
Then create the Add service event
addService = (e) = > {
this.setState({
serviceList: [...this.state.serviceList, this.state.serviceValue],
});
};
Copy the code
Note that setState() cannot use the array method push(), because push() does not return a value, resulting in the corresponding key value changing to number
// Error
addService = (e) = > {
this.setState({
serviceList: this.state.serviceList.push(this.state.serviceValue),
});
};
// You can use concat instead
addService = (e) = > {
this.setState({
serviceList: this.state.serviceList.concat(this.state.serviceValue),
});
};
Copy the code
6.4 Deleting a Service
First we need to bind
<ul>
{this.state.serviceList.map((item, index) = > {
return (
<li key={index} onClick={this.deleteService.bind(this, index)} >
{item}
</li>
);
})}
</ul>
Copy the code
Bind (this, xx); if you write Fn(xx), it will become a direct call
Then we create the delete event
// Delete the service
deleteService = (index) = > {
React forbids direct manipulation of state, so we create a new variable to operate on
let list = this.state.serviceList;
list.splice(index, 1);
this.setState({
serviceList: list,
});
};
Copy the code
This is the end of the little project.
7. Component splitting
Although the above small project has been completed, in the actual work, we must carry out component splitting, which is conducive to our later maintenance.
Start by listing the entire code, noting where you need to split it
import React, { Component } from 'react';
class Xiaojiejie extends Component {
constructor() {
super(a);// Call the parent constructor, fixed
this.state = {
/** New service content */
serviceValue: ' './** Service list */
serviceList: ['Head massage'.'Essential oil push back']}; }render() {
return (
<div>
<div>
<input
value={this.state.serviceValue}
onChange={this.serviceChange}
type="text"
/>
<button onClick={this.addService}>Increase the service</button>
</div>Split {/ * * /}<ul>
{this.state.serviceList.map((item, index) => {
return (
<li key={index} onClick={this.deleteService.bind(this, index)} >
{item}
</li>
);
})}
</ul>
</div>
);
}
// Reactive data binding
serviceChange = (e) = > {
this.setState({
serviceValue: e.target.value,
});
};
// Add services
addService = () = > {
this.setState({
serviceList: this.state.serviceList.concat(this.state.serviceValue),
});
};
// Delete the service
deleteService = (index) = > {
let list = this.state.serviceList;
list.splice(index, 1);
this.setState({
serviceList: list,
});
};
}
export default Xiaojiejie;
Copy the code
7.1 Creating a Service List Component
Under the Xiaojiejie folder, create a new xiaojiejiejieitem.js and write the infrastructure
import React, { Component } from 'react';
class XiaojiejieItem extends Component {
render() {
return <li>Service List module</li>; }}export default XiaojiejieItem;
Copy the code
7.2 Value Transfer of Parent and Child Components
Our requirement is functional modularity. Once the service list component is removed, we need to introduce sub-components, and then pass the service list parameters to the sub-components to make them visible
The father the son
Parent component writing
// Introduce the child components first
import XiaojiejieItem from './XiaojiejieItem';
// Using the subcomponent, pass the parameters to the subcomponent, similar to vUE: custom attribute name = value format, subcomponent replaces the previous li tag, also need to set the key value
<ul>
{this.state.serviceList.map((item, index) => {
return <XiaojiejieItem key={index} content={item} />;
})}
</ul>;
Copy the code
Subcomponent writing
// accept this as this.props. Xx
class XiaojiejieItem extends Component {
render() {
return <li>{this.props.content}</li>; }}Copy the code
The page should display normally, but we found that there is still a deletion service function missing, which requires the child component to pass the index to the parent component and then call the parent component’s method to delete it
Child the parent
Parent component writing
// Pass the index and the method to delete the service to the child component
<ul>
{this.state.serviceList.map((item, index) = > {
return (
<XiaojiejieItem
key={index}
content={item}
index={index}
deleteService={this.deleteService}
/>
);
})}
</ul>
Copy the code
Subcomponent writing
// Bind the click event to Li
class XiaojiejieItem extends Component {
render() {
return <li onClick={this.handleServiceList}>{this.props.content}</li>;
}
// Pass the index to call the parent component method
handleServiceList = () = > {
this.props.deleteService(this.props.index);
};
}
Copy the code
8. Simple application of PropTypes
8.1 role
Verify the validity of the incoming data, and the JavaScript console throws a warning when invalid data is passed to the props. For performance reasons, propTypes are validated only in the development environment.
8.2 Simple Use
In xiaojiejieitem.js first introduced
import PropTypes from 'prop-types';
Copy the code
Then go and set the types of the different parameters, note that they are written outside the class
// propTypes here start with lower case
XiaojiejieItem.propTypes = {
content: PropTypes.string,
deleteService: PropTypes.func,
index: PropTypes.number,
// Set a non-required parameter and add the keyword isRequired so that no error will be reported if the value is not passed
name: PropTypes.string.isRequired,
};
Copy the code
After setting the type of the parameter, an error will be reported on the console if the parameter passed by the parent component does not match the type we defined
React Lifecycle
9.1 Four major stages
The React lifecycle can be divided into four major phases:
Initialization
: Initialization phaseMounting
: Mount phaseUpdation
: Component update phaseUnmounting
: Destruction stage
9.2 Each life cycle and its usage
1. Mount and uninstall process
componentWillMount()
: is called before a component renders. It is rarely used, but more often used during server-side rendering. It represents the process that the React 17 version is about to be abandoned when the component has undergone a constructor() initialization of the data, but has not rendered the DOM.componentDidMount()
When the component is rendered for the first time, the DOM node has been generated. Ajax requests can be made here, and the component will be rendered again after the setState data is returned.componentWillUnmount()
: is called immediately before the component is removed from the DOM, usually for destructionsetTimeout, setInterval
As well asremoveEventListener
.
2. Update process
getDerivedStateFromProps(nextProps, prevState)
: is called before the Render method is called, and is called both during the initial mount and during subsequent updates. It should return an object to update state, if returnednull
Nothing is updated.shouldComponentUpdate(nextProps,nextState)
: Controls whether the component is updated by returning a Boolean valuePerformance optimization
.Because rerendering the React parent causes all child components to rerender as well
, so you need to make a judgment in this life cycle of the child component.getSnapshotBeforeUpdate(prevProps, prevState)
: called before the last render output (committed to the DOM node). It enables the component to capture some information from the DOM before changes are made. Any return value from this life cycle is passed as a parameter tocomponentDidUpdate()
.componentDidUpdate(prevProps,prevState)
React will only enter componentDidmount after the first successful initialization of the component after it has been updated, and will enter this life cycle after every re-rendering.render()
: The Render function inserts the DOM structure generated by JSX. React generates a virtual DOM tree. At each component update, react uses its diff algorithm to compare the old and new DOM trees before and after the update. And re-render.getDerivedStateFromError()
: This life cycle is invoked after a descendant component throws an error. It takes the thrown error as an argument and returns a value to update state
Refer to the article
- React16 Free Video Tutorial (28 episodes)
- React lifecycle
- React 英 文 版