After reading this article, your React can be put on your resume
author's foreword
- This article records the basis of React. Although React is very updated, theoretically all versions are available. Please rest assured to read
- The React version used for writing the article: 18.2, because the basics are relatively basic, there is no need to worry about mistakes and bugs
- Although React routing is changed in this article, it is not discussed in detail (mainly due to frequent updates and large differences between versions, so a separate article will be published in the future)
- The full text has a total of 24,000 words (the code sheet accounts for about 30%, and the main text accounts for about 70%). The estimated reading time is about 75 minutes. The code has been annotated in detail, and the article has a practical demo. It is recommended to save for repeated reading
Article directory
-
- After reading this article, your React can be put on your resume
-
- author's foreword
- About React
- Features of React
- Ways to use React
- Comparison between React and native DOM
- React/JSX syntax specification
- Custom Components in React
- React scaffolding (create-react-app)
- Prerequisites for installing scaffolding
- Create-react-app (React scaffolding) installation
- Introduction to create-react-app (React Scaffolding)
- Regarding the loss of this pointing
- Improve the development of the shopping cart counting module
- functional components
- life cycle hook function
- Functional Components and Hooks
- React Hook: Hook
- Summarize
- React Routing Navigation
- end
-
About React
React is a framework for 构建用户界面的JS库
(essentially a MVVM framework) - no HTML and CSS involved
Chinese official website : React Chinese official document
- It is an open source front-end framework under FaceBook
- The react on this site is up-to-date, the earliest version dates back to 2013, and the current latest version is
18.2
React is a构建用户界面
JavaScript library for (officially modest)
React part of the library compared to Vue
Contrast Vue's Vuex, Vuerouter, Vue-UI
Features of React
- Declarative : Create an interactive and Vue-like virtual DOM for the MVVM framework React, and refresh the DOM when the data changes (data responsive)
- Component programming :
- Good compatibility :
- Projects that Vue can create :
网站,H5,WebApp,混合式APP
- Items that React can create :
网站,H5,WebApp,原生App(JS=>JAVA/OC)
- Projects that Vue can create :
Ways to use React
import as script
The specific CSN address is as follows:
// 编译
https://unpkg.com/[email protected]/babel.min.js
// react-dom
https://unpkg.com/react-dom@18/umd/react-dom.development.js
// react本体
https://unpkg.com/react@18/umd/react.development.js
And the sorted imports script标签
are as follows
// 注意导入顺序小心被开dddd
<!-- 为页面提供虚拟的DOM元素 用于创建虚拟DOM-->
<script src="./js/react.development.js"></script>
<!-- 为页面提供ReactDOM对象用于把虚拟的DOM元素和真实DOM元素映射起来 -->
<script src="./js/react-dom.development.js"></script>
Note 导入顺序
that otherwise an error will be reported, for example:
Uncaught TypeError: Cannot read properties of undefined(reading'__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED')
supplementary link
React's official documentation introduces: How CDN imports react
Comparison between React and native DOM
Realize demo requirements
I need to add a button in #app with the following effect
Native implementation requirements
- Create new DOM element button
<script> let button = document.createElement("button"); // 添加title悬浮显示 button.title = "点击我一下试试"; // 添加className button.className = "btn btn-primary"; // 添加内容 button.innerHTML = "我是一个小按钮"; </script>
- Find the parent container DOM element: div
<script> // - 查找父容器DOM元素:div let app = document.getElementById("app"); </script>
- Add child element to parent element
<script> // - 在父元素中添加子元素 app.appendChild(button); </script>
Defects in native implementation requirements
The elements provided by the DOM objects provided in the dom standard are all heavyweight elements. If the page needs to be operated every time the page changes, it will be too cumbersome and will affect the performance of the page (refer to the figure below, the DOM operation object is too bloated, it will Take up a lot of RAM), in fact, when we print the app and button, we will find that we only added a few attributes above, but their DOM objects are very bloated
console.dir(app);
Solution: Virtual DOM
As we all know, the native DOM is too bloated and consumes a lot of performance, so the virtual DOM is born from the operation.
The comparison between virtual DOM and native DOM
- Native DOM :
DOM对象臃肿大量消耗空间
(After creating a DOM element, all DOM attributes will be created by default regardless of whether you use it or not) - Virtual DOM :
简化DOM
(Simply speaking, how many DOM attributes you write corresponds to several objects)
Example: React’s virtual DOM
React implementation requirements
normal fulfillment requirements
- Create virtual buttons
<script> // - 创建虚拟的button // 1:标签名 2:属性 let vbutton = React.createElement( "button", // 标签名 { title: "我是React家的按钮", className: "button" }, // 对象:用于存储标签属性 "React button" // 内容:innerHTML ); </script>
- Find the parent container DOM element: div converted to a virtual DOM container
<script> // 创建虚拟的vapp容器(创建一颗虚拟的DOM树的根元素让其与app元素对应起来) let vapp = ReactDOM.createRoot(app); // 可以直接写id属性也可以getElementById获取之后再来获取 </script>
- Add child tags in virtual DOM parent element
<script> // - 在虚拟DOM父元素中添加子标签 //渲染上子元素 render:渲染(React会经常用) vapp.render(vbutton); </script>
Simplify implementation requirements
The consumption of operating the virtual DOM is much lower than that of the real DOM, but the operation is too cumbersome, so let's try to simplify it
first: let's write the code directly and try
let vbutton = (
<button
title="1"
class="button"
>
React button
</button>
);
As a result,
we can see that it reported an error, but don't be discouraged, this method is available, but first we have to review TypeScarip 's JSX . Click the link above
to see an introduction to JSX. I won't do too much here. has summarized
JSX(Javascript XML)
Javascript XML : Use XML syntax to create HTML elements, which is part of TypeScarip.
Tip: Since the browser does not support TS, it does not support JSX syntax, so it needs a TS compiler to convert it into JS code—— BaBal
Let's try it next Try the babel compiler
First open the babel online compiler and let's compile the react code
- After opening the link as shown in the figure below, it will be as shown in the figure below
- Next, let's simply write a label to try
After pasting, you will find that the code is generated on the right,<button title="我是React的button标签" class="react-button">React button</button>
and now put it into the react code to trylet vbutton = /*#__PURE__*/ React.createElement( "button",{ title: "\u6211\u662FReact\u7684button\u6807\u7B7E", className: "react-button", },"React button");
- As a result,
we can see that the success is displayed
React/JSX syntax specification
Grammar specification [ key ]
- JSX tag/component names are strictly case-sensitive
- Components corresponding to HTML tags must use the big hump naming method
- Custom component names must use the upper camel case naming method
- There can only be one root element in a piece of JSX
- A piece of JSX can be written in multiple lines, and the outermost layer can be
()
enclosed indicate that this is a whole end of JSX - HTML tags in JSX must be closed; for example
<hr>
it can be written as<hr></hr>
- The tag attribute in JSX is not equivalent to HTML; if
class
the attribute is in JSX, it should beclassName
- JSX can be used
{ }
for data binding (内容绑定
,样式绑定
,属性绑定
,事件绑定
...
) - There is no concept of attribute binding in JSX (similar to Vue's
v-model
,v-bind
) unified as{}
- To set element binding, you can define an object and then bind it, or you can directly write the object in brackets
- Event binding:
在Vue里面叫v-on/@click
There are some special APIs in React. Other basics are the same as writing native ones更改事件名
. - Event binding parameter passing: We all know that parentheses need to be added if parameters need to be passed in native, but adding parentheses in React will be executed immediately, so the click will be invalid, so the solution is to use and
回调函数
to函数
solve
demo example
After the above description, it is estimated that everyone has already understood the basic operations and logic of JSX and React. Next, let’s do a few small demos to experiment with the above specifications.
- Make some methods and declare functions
// 创建一个公共值 let num = 20; // 设置元素绑定可以定义一个对象 var style = { color: "red", backgroundColor: "#000000", }; // style={style} // 也可以写为 // style={ { // color: "red", // backgroundColor: "#000000", // }} // 定义事件 // 两种写法都是可行的 var numAdd = function () { num++; console.log(num); }; function numCount() { num++; console.log(num); }
- Create virtual DOM elements
// - 创建虚拟的DOM元素 // 一段JSX中只能有一个根元素 // 在react中没有属性绑定的概念(v-model,v-bind) // 加上双引号就代表为字符串所以不能写 let buyCount = ( <div> <button onClick={ numAdd}>-</button> <span title={ num} style={ style} > { num} </span> <button onClick={ numCount}>+</button> </div> );
- Convert real DOM parent container to virtual DOM container
// - 把真实的DOM父容器转换为虚拟的DOM容器 let vapp = ReactDOM.createRoot(app);
- Render child elements inside a virtual DOM parent container
// - 在虚拟的DOM父容器里面渲染子元素 vapp.render(buyCount);
Custom Components in React
The early React design was to take care of programmers who wrote C and Java, so React provided two syntaxes for custom components
function syntax
- Custom Component Syntax 1: Functional Components
// 自定义组件语法1:函数式组件 function Rating() { // 这是JSX return <div>❤❤❤❤❤❤</div>; }
- Create a virtual dom
// 1,创建虚拟dom // Rating标签相当于span标签 let Rat = <Rating></Rating>;
- Convert real DOM container to virtual DOM container
// 2,把真实DOM容器转换为虚拟的DOM容器 let vapp = ReactDOM.createRoot(app);
- Render virtual DOM elements in virtual DOM
// 3,在虚拟DOM中渲染虚拟的DOM元素 vapp.render(Rat);
- result
- why does it show
React custom component parameter passing
** Still above list**
<script type="text/babel">
// 自定义组件语法1:函数式组件
function Rating() {
// 这是JSX
return <div>❤❤❤❤❤❤</div>;
}
// 1,创建虚拟dom
// Rating标签相当于span标签
let Rat = (
<Rating
color="red"
count={
9}
/>
);
// 2,把真实DOM容器转换为虚拟的DOM容器
let vapp = ReactDOM.createRoot(app);
// 3,在虚拟DOM中渲染虚拟的DOM元素
vapp.render(Rat);
</script>
The parent component is passed to the child component, in fact, just write it directly like Vue
Subcomponents accept parameters
And subcomponents only need to write a formal parameter in the callback function to receive parameters
// 自定义组件语法1:函数式组件
function Rating(suibian) {
// 这是JSX
console.log(suibian);
return <div>❤❤❤❤❤❤</div>;
}
// 1,创建虚拟dom
// Rating标签相当于span标签
let Rat = (
<Rating
color="red"
count={
9}
/>
);
// 2,把真实DOM容器转换为虚拟的DOM容器
let vapp = ReactDOM.createRoot(app);
// 3,在虚拟DOM中渲染虚拟的DOM元素
vapp.render(Rat);
We can see it
, but what if I write one without passing in the past 随便
?
<script type="text/babel">
// 自定义组件语法1:函数式组件
function Rating(suibian) {
// 这是JSX
console.log(suibian);
return <div>❤❤❤❤❤❤</div>;
}
// 1,创建虚拟dom
// Rating标签相当于span标签
let Rat = <Rating />;
// 2,把真实DOM容器转换为虚拟的DOM容器
let vapp = ReactDOM.createRoot(app);
// 3,在虚拟DOM中渲染虚拟的DOM元素
vapp.render(Rat);
</script>
The answer is: empty object
Let's improve it next (I don't want to be too wordy, just read the comments)
<script type="text/babel">
// 自定义组件语法1:函数式组件
function Rating(suibian) {
// 这是JSX
console.log(suibian);
// suibian: 形参值为传入的参数
let hearts = "";
// 书写代码
for (let i = 0; i < suibian.count; i++) {
hearts += "❤";
}
// 返回代码
return <div style={
{
color: suibian.color }}>{
hearts}</div>;
}
// 1,创建虚拟dom
// Rating标签相当于span标签
let Rat = (
<Rating
color="red"
count={
20}
/>
);
// 2,把真实DOM容器转换为虚拟的DOM容器
let vapp = ReactDOM.createRoot(app);
// 3,在虚拟DOM中渲染虚拟的DOM元素
vapp.render(Rat);
</script>
The effect is as follows
Summary of React custom components
- To create a component function name, the first letter of the component name must be capitalized
- Using components can be used but labels can also use double labels (but the label should be closed)
React declares class syntax for custom components
Class-style components - embodies the idea of object-oriented programming (90s: Java language)
//创建组件
class Rating extends React.Component {
render( ){
return JSX //通过this.props读取当前组件获得的属性
}
}
//使用组件
let e = <Rating 属性名=值/>
React scaffolding (create-react-app)
react scaffolding: similar to Vue Cli
an official tool called create-react-app
, it can be used to create blank projects
Prerequisites for installing scaffolding
First check if your node version is greater than 12.0
node -v
Mine is 16.16 (if I am developing Hongmeng, I need to uninstall and install a version around 14.2. Let’s not talk about this here for the time being. There will be an article about Hongmeng [imply attention])
Make sure your npm warehouse address is a domestic mirror source, otherwise the download may fail (the project package is about 200MB, and if you are unstable and disconnected abroad, you can only download it again)
npm config get registry
Mirror source address comparison table
For example, mine (the picture below is the default source in the United States, I reinstalled node for a screenshot)
is set to the domestic npm warehouse
npm config set registry https://registry.npmmirror.com/
Create-react-app (React scaffolding) installation
Official document : Building a local React development environment
- Download tool
npx create-react-app 项目名
NPX: Node Package Executor Node package executor is a Node.js package execution tool officially provided by Node.js
The following is a screenshot after executing the installation command
- run tool
cd 项目名
- After running the development server
npm start
installation is complete
Introduction to create-react-app (React Scaffolding)
Introduction to the use of folders and files in React scaffolding
How and how to write React pages
How to use and write components
Regarding the loss of this pointing
-
The method in the class is only possible if the event processing function is the this pointer is lost
-
reason:
严格模式下this指向undefind
-
The this in JS
function(){}
points to the caller of the function (but you can't see where the function is declared)——this does not point to the component object,JSX中的所有元素都是虚拟的DOM元素,不能作为HTML事件源对象
——this不指向HTML元素
.JSX中的事件处理函数会被编译为“严格模式”下的全局函数
——其中this指向undefinded
-
Solution 1 : Arrow function - event handler function declaration
设计为箭头函数
f1 = () => { // this指向上级 }; <button onClick={ () => { this.f1(); }}>-</button>
Parentheses cannot be written in this method (actual parameters cannot be passed)
-
Solution 2 : Arrow function - specify an arrow function for the event, and the function execution is to call the target function
f1 = (实参) => { // this指向上级 }; <button onClick={ 实参 => this.f1(实参);>-</button>
This method can pass arguments
-
Solution 3 : Use the bind method in the JS function to return a copy of itself, the only difference is that this points to the specified object
demo: [JavaScript Advanced] case reference article for bind, call, and apply
: [JavaScript] bind , call and apply deconstruction and class constructorf1 = (形参) => { // this指向上级 }; <button onClisk={ this.f1.bind(this)}></button> // bind:绑定/固定 将函数中的this指向固定指向特定对象
-
Solution 4 : Use the constructor in the class constructor
Reference article: [JavaScript] ES6 deconstruction and class constructor
official documentation: Documentation - Adding interactive functions to components
This method is actually the method used by the official documentation. You can go to the official documentation for details. In daily use,箭头函数
the methods in scheme 1 and scheme 2 are sufficient
Improve the development of the shopping cart counting module
The use and setting of the state attribute
This property is equivalent to the page file in Vue
the.vue
vdata属性
Declare properties
state = {
uname: "某琨用过的篮球",
count: 10,
};
use attribute value
this.state.xxx
: to find the attribute value
so we can write as
<div>{this.state.count}</div>
In the same way, we can also manipulate its value in this way
Modify the value of State and load it to the page is
Combined with the above, since we can get it, we should be able to modify it, let's try
numAdd = () => {
// 添加
this.state.count++;
console.log(this.state.count);
};
render() {
return (
<React.Fragment>
<div>{
this.state.count}</div>
<button onClick={
this.numAdd}>+</button>
</React.Fragment>
);
}
But after running, we found that although it is printed, the liquid level is not displayed. Why is this?
In fact, the difference is as follows
The difference between Vue and React property refresh [key]
- The data responsiveness of Vue.js
Push Based
, while the data responsiveness in React isPull Base
- Push Based: When the data is modified, the rendering system will be notified to automatically refresh
- Pull Based: When the data is modified, the page will not be automatically rendered, so it needs to perform rendering
this.setState()
Refresh the data on the page
Through the above description, we will find the update mode of the data in the state in React, so the code can be written like this, pay attention to the comments!
import React, {
Component } from "react";
// 创建页面
export default class App extends Component {
// 声明属性
state = {
uname: "某琨用过的篮球",
count: 10,
};
numAdd = () => {
// 添加
// this.state.count++;
// console.log(this.state.count);
// 这样直接修改变量是不会去刷新而渲染的
this.setState({
count: this.state.count + 1,
});
};
numCount = () => {
// 减少
this.setState({
count: this.state.count - 1,
});
};
render() {
return (
<React.Fragment>
<button onClick={
this.numCount}>-</button>
<div>{
this.state.count}</div>
<button onClick={
this.numAdd}>+</button>
</React.Fragment>
);
}
}
We found that it is now available
functional components
Next, let's write a parent-child component
life cycle hook function
There are 7 hook functions in react
mount phase
- constructor: The component is created (equivalent to creatactive in Vue)
- render: component rendering content
- componentDidMount: The component is finished hanging (equivalent to Vue's Mounted)
update phase
- shouldComponentUpdate: Does this attribute update or status update modification need to update the view? If it returns a true it will render
- reder: component rendering
- componentDidUpdate: If rendering is allowed, it will be called after execution, otherwise it will not be executed
uninstall phase
- componentWillUnmount: The component is about to be unmounted
- At this stage, you can start to turn off the home page carousel timer, websockio and other services.
- The function is similar to beforeDestroy in Vue
practice demo
Create a new component and paste the following code after pouring it in
import React, {
Component } from "react";
export default class Child extends Component {
constructor() {
super();
console.log("1-constructor当页面被加载了");
}
componentDidMount() {
console.log("3-componentDidMount组件被挂载");
}
// 应该让组件更新嘛?
shouldComponentUpdate(newProps, newState) {
// 如果想要获取到新的数据就要写上下面这两个参数
console.log(newProps, newState);
// 其实可以在这个上面添加一个if语句来判断一下
// console.log(this.state.num % 2);
if (this.state.num % 2) {
console.log("4-shouldComponentUpdate:应该让组件更新嘛?");
console.log("是的我希望组件更新");
return true;
} else {
console.log("4-shouldComponentUpdate:应该让组件更新嘛?");
console.log("我不希望更新组件");
return false;
}
}
// 完成更新之后
// 如果不更新的话下面的钩子函数将不会执行
componentDidUpdate() {
console.log("6-完成了更新");
}
componentWillUnmount() {
console.log("7-组件即将卸载");
}
// 组件数据
state = {
num: 1,
};
// 组件方法
f1 = () => {
this.setState({
num: this.state.num + 1 });
};
// 开始渲染内容
render() {
console.log("2-render渲染内容");
return (
<div
style={
{
backgroundColor: "red", userSelect: "none", margin: "20px" }}>
<h3>我是子组件哦</h3>
<p>计数器:{
this.state.num}</p>
<button onClick={
this.f1}>点击计数器</button>
</div>
);
}
}
Functional Components and Hooks
The components defined in React are divided into: function and class components.
In the early days, people preferred to use class components because functional components lack state. The lifecycle method
officially provides a new function for functional components from React 16.8——Hook, which is specially used To "hook" more functions for functional components, such as: the method of state life cycle... At the same time, due to the simplicity of functional components, everyone began to prefer to use functional components
React Hook: Hook
Hook is a lower version available after React 16.8. You can skip
the official document: Introduction to Hook
- Every hook in React is a method
- The official provides a total of 15 hook functions. In order to distinguish them from ordinary functions, all hook functions must be
useXxx
written in the format of - All hook functions can only be called in functional components - not for class components
- The official requirement is that all hook functions can only be called at the top of the function component
useState()
// 正确
if(useState()) {
}
// 错误
for (){
useState()
}
// 错误
function inner() {
useState()
}
// 错误
- Each hook function can extend the functionality of the component
Next, let's talk about how to use the hook.
useState hook function
First let's write a test
let x = useState(0);
let y = useState(5);
console.log(x, y);
Print the result
and we can see that it returns an array.
If you don’t understand it yet, let’s use deconstruction to take a look.
let [cont, f2] = useState(666);
console.log("cont", cont);
console.log("f2", f2);
Now that we know the meaning of the two values, let's write a demo to deepen our understanding
import React, {
useState } from "react";
export default function Child() {
// 点击计数器-状态变量
// let x = useState(0);
// let y = useState(5);
// console.log(x, y);
// 解构语法
let [cont, setCont] = useState(666);
console.log("cont", cont);
console.log("setCont", setCont);
return (
<div>
<h3>这里是计数器(子组件)</h3>
<p>计数器:{
cont}</p>
<button
onClick={
() => {
setCont(667);
}}>
点击添加
</button>
</div>
);
}
It is estimated that everyone will spray me again. What setCont to write is easy to confuse. Here, this parameter is optional, and 只是一个方法名而已(解构时定义)
I can write it like this
import React, {
useState } from "react";
export default function Child() {
// 点击计数器-状态变量
// let x = useState(0);
// let y = useState(5);
// console.log(x, y);
// 解构语法
let [cont, suibian] = useState(666);
console.log("cont", cont);
console.log("suibian", suibian);
return (
<div>
<h3>这里是计数器(子组件)</h3>
<p>计数器:{
cont}</p>
<button
onClick={
() => {
suibian(667);
}}>
点击添加
</button>
</div>
);
}
If you still can’t write like this, you can go home and wash it (funny)
The number is mentioned above. Next, let’s try a string.
In fact, useState is not only used for numbers but also for strings. For example, I wrote a way to change after clicking.
import React, {
useState } from "react";
export default function Child() {
// 点击计数器-状态变量
// let x = useState(0);
// let y = useState(5);
// console.log(x, y);
// 解构语法
let [cont, suibian] = useState("你瞅啥");
console.log("cont", cont);
console.log("suibian", suibian);
return (
<div>
<h3>这里是子组件</h3>
<p>提示:{
cont}</p>
<button
onClick={
() => {
suibian("瞅你咋滴");
}}>
点击添加
</button>
</div>
);
}
In fact, it is also possible to useState to define a string. 并不只能用于数字
At this time, some savages came to ask. 这个玩意有长度限制嘛?
Answer:是没有的
useEffect hook function
How to use useEffect hook function (life cycle method/side effect hook)
useEffect(()=>{
// 此处就是一个生命周期方式
})
Note: The lifecycle method provided by the hook is unnamed (for example, Vue is named (Monuted...))
Summarize
Can class and function components be mixed
Subcomponent
parent component
The results can display the answer normally
and can be mixed
React Functional Component Classic Mistakes
Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
An infinite loop occurs in a functional component, for example:
import React, {
useState } from "react";
import Child from "./Child";
export default function Parent() {
// const [Shower, setShower] = useState(false);
const [Shower, setShower] = useState(true);
return (
<div style={
{
backgroundColor: "#afa" }}>
<h2>这里是父组件</h2>
<button onClick={
setShower(!Shower)}>显示子组件</button>
{
Shower && <Child />}
</div>
);
}
The solution is to write a function outside to manipulate the data, and operate the data after clicking
import React, {
useState } from "react";
import Child from "./Child";
export default function Parent() {
// const [Shower, setShower] = useState(false);
const [Shower, setShower] = useState(true);
function showChar() {
setShower(!Shower);
// 修改状态的方法都是异步的
}
return (
<div style={
{
backgroundColor: "#afa" }}>
<h2>这里是父组件</h2>
<button
onClick={
() => {
showChar();
}}>
显示子组件
</button>
{
Shower && <Child />}
</div>
);
}
About 6 life cycle methods provided by React Hook
In fact, some hook functions of general React are useEffect
evolved. The Chinese translation means that 使用效果
useEffect
there are two common ways of writing, and there are two parameters carried, and the second parameter can not be written (will be described below) The format is as follows
useEffect(() => {
// 执行代码
});
or
useEffect(() => {
// 执行代码
},[依赖项目]);
In fact, this dependent project can be understood as monitoring. If the dependency list is empty, it means that there is no difference between listening and monitoring.
Some hook functions when the component is mounted
This branch is mainly to talk about the things when the components are mounted.
Let's write a simple demo to see it.
import React, {
useEffect, useState } from "react";
export default function Child() {
/*hook 提供的生命周期方法一共有7个*/
useEffect(() => {
// console.log("生命周期方法:页面挂载时 - 1 = componentDidMount");
console.log("生命周期方法:组件挂载+任意属性/状态发生改变");
// componentDidMount+componentDidUpdate+componentWillUnmount
});
/*******************************/
// 点击计数器-状态变量
// let x = useState(0);
// let y = useState(5);
// console.log(x, y);
// 解构语法
let [cont, setCont] = useState(() => {
return "abc";
});
// console.log("cont", cont);
// console.log("setCont", setCont);
return (
<div>
<h3>这里是子组件</h3>
<p>提示:{
cont}</p>
<button
onClick={
() => {
setCont("瞅你咋滴");
}}>
点击添加
</button>
</div>
);
}
Replace the code and
run it as shown in the figure below
, but since it is a life cycle hook function, why is there only one hook? Shouldn't it have parameters like Vue?
Don't worry, let's talk about useEffect
the second variable below
- The first parameter is the lifecycle method
- The second parameter is the method that the life cycle depends on
Still the previous demo this time we add the second parameter
import React, {
useEffect, useState } from "react";
export default function Child() {
/*hook 提供的生命周期方法一共有7个*/
useEffect(() => {
// console.log("生命周期方法:页面挂载时 - 1 = componentDidMount");
console.log("生命周期方法:组件挂载+任意属性/状态发生改变1");
// componentDidMount+componentDidUpdate+componentWillUnmount
});
/*******************************/
// 点击计数器-状态变量
// let x = useState(0);
// let y = useState(5);
// console.log(x, y);
// 解构语法
let [cont, setCont] = useState(() => {
return "abc";
});
let [conts, setConts] = useState(() => {
return "abc";
});
useEffect(() => {
// console.log("生命周期方法:页面挂载时 - 1 = componentDidMount");
console.log("生命周期方法:组件挂载+任意属性/状态发生改变2");
// componentDidMount+componentDidUpdate+componentWillUnmount
}, [conts]);
// 第一个参数为生命周期方法
// 第二个参数为生命周期依赖的方法
// console.log("cont", cont);
// console.log("setCont", setCont);
return (
<div>
<h3>这里是子组件</h3>
<p>提示:{
cont}</p>
<button
onClick={
() => {
setCont("瞅你咋滴");
}}>
点击添加
</button>
</div>
);
}
But after a few rounds of operation, we found that
we found that the consts variable corresponding to the second hook function tree will only be triggered when there is a change (here is the mount rendering)
In fact, what we often see is that
when the dependency list of the second parameter is empty, any data state change will not call
the demo again as follows
import React, {
useEffect, useState } from "react";
export default function Child() {
/*hook 提供的生命周期方法一共有7个*/
useEffect(() => {
// console.log("生命周期方法:页面挂载时 - 1 = componentDidMount");
console.log("生命周期方法1:组件挂载+任意属性/状态发生改变");
// componentDidMount+componentDidUpdate+componentWillUnmount
});
/*******************************/
// 点击计数器-状态变量
// let x = useState(0);
// let y = useState(5);
// console.log(x, y);
// 解构语法
let [cont, setCont] = useState(() => {
return "abc";
});
let [conts, setConts] = useState(() => {
return "abc";
});
useEffect(() => {
// console.log("生命周期方法:页面挂载时 - 1 = componentDidMount");
console.log("生命周期方法2:组件挂载+任意属性/状态发生改变");
// componentDidMount+componentDidUpdate+componentWillUnmount
}, [conts]);
useEffect(() => {
// console.log("生命周期方法:页面挂载时 - 1 = componentDidMount");
console.log("生命周期方法3:组件挂载+任意属性/状态发生改变");
// componentDidMount+componentDidUpdate+componentWillUnmount
}, []);
// 第一个参数为生命周期方法
// 第二个参数为生命周期依赖的方法
// console.log("cont", cont);
// console.log("setCont", setCont);
return (
<div>
<h3>这里是子组件</h3>
<p>提示:{
cont}</p>
<button
onClick={
() => {
setCont("瞅你咋滴");
}}>
点击添加
</button>
</div>
);
}
We found that there is no trigger after the component is mounted
About methods related to component uninstallation
In fact, it is almost the same as above. The following code has comments, just look at it.
// 关于组件卸载相关的方法
useEffect(() => {
return () => {
console.log("生命周期方法-4:组件卸载+任意属性/状态发生改变");
};
});
// 关于组件卸载相关的方法同时监听某个值的改变
useEffect(() => {
return () => {
console.log("生命周期方法-5:组件卸载+指定属性/状态发生改变");
};
}, [conts]);
// 只有组件卸载,不依赖于任何状态改变
useEffect(() => {
return () => {
console.log("生命周期方法-6:只有组件卸载,不依赖于任何状态改变");
};
}, [conts]);
Add the above code on the basis of the original code, run it and we can see the following results
In fact, we have finished talking about the life cycle of React here,
but after learning here, we may have learned a lot, but this is far from our goal 简历上写上熟练使用React是远远不够的
, so continue Come down to our point
React Routing Navigation
Routing and Navigation Functions
- Assign access address for each page----routing dictionary
- Routing navigation, jumping from one page to another
- Pass parameters when jumping
There are two routing navigation modules in the React ecosystem
- React-Router-DOM: used in browser projects: H5, website
- Router-Navigation: Used in projects without browsers: RN’s native APP (this component will not be discussed for the time being, because this component
React native
is used a lot, and we don’t use it now, and I will talk about it in an article later when I have time)
Next, let's take a look at the package
information below.
Install
npm i react-router-dom
** After the installation is complete, package.json
there will be **
** After adding, we can add the route **
add route
- When using it, you first need to import it on demand in index.js
import { createBrowserRouter, RouterProvider } from "react-router-dom"; // createBrowserRouter:创建路由对象 // RouterProvider:挂载对象
- Then create a route object
But before that, you need to// 创建路由器,包括词典 let router = createBrowserRouter([ { path: "路径以斜杆开头", element: 组件简单名, }, // 例如 { path: "*", element: <NoFound />, }, ]);
import
import the page as aboveimport NoFound from "./pages/NoFound";
mount route
We said above that after creating the routing object, we cannot use the routing directly, so we need to mount the routing.
We need to use the second method introduced above ( RouterProvider
)
to use
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
// 注意看这里
<RouterProvider router={
router} />
</React.StrictMode>,
);
end
- Seeing this, I believe that your React can basically be put on your resume. Welcome to follow and look forward to future article updates
- For technical communication, you can add my WeChat
startrrshutsan
(valid for a long time) to pull you into the communication group