React 全家桶
React 基础 React-Router PubSub Redux Ant-Design
React 介绍
做什么
React 主要是用来操作 DOM 呈现页面(将数据渲染成 HTML 的开元 JavaScript 库)
谁开发
为什么学
- 原生 JS 操作 DOM 繁琐且效率低(DOM-API)
- 使用 JS 直接操作 DOM,浏览器会打大量的重绘重排
- 原生 JS 没有组件化编码方案,代码复用率很低
React 的特点
- 采用组件化模式,声明式代码,提高开发效率及组件复用率
- 在 React Native 中可以使用 React 语法进行移动端开发
- 使用虚拟 DOM+优秀的 diff 算法,尽量减少与真是 DOM 的交互
学习 React 之前要掌握的 JS 基础知识
- this
- class
- ES6
- npm
- 原型及原型链
- 数组常用方法
- 模块话
babel
ES6 ---> ES5 JSX ---> JS
React 学习
复习
01-类的基本知识
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<script type="text/JavaScript">
/**
* 总结
* 1. 类的实例不是必须写的,需要对实例进行一些初始化操作挥着添加属性的属性需要写
* 2. 如果A类继承了B类,且A类写了构造器,那么A类构造器中 super() 必须要调用
* 3. 类中所定义的方法,都是放在类的原型对象上,供实例去使用
*/
class person {
// 构造器方法
constructor(name, age) {
// 构造器中的this-->类的实例对象(也就是谁new的)
this.name = name;
this.age = age;
}
// 一般方法
speak() {
// speak 方法放在了--->类的原型对象上; 供实例使用
// 通过person实例调用时候,speak的this就是person实例
console.log("我叫", this.name, "我年龄是", this.age);
}
}
const p1 = new person("小张", 100);
const p2 = new person("小红", 101);
console.log(p1); // person {name: '小张', age: 100}
console.log(p2); // person {name: '小红', age: 101}
console.log(p1.speak()); //我叫 小张 我年龄是 100
// 创建一个student类继承于person
class student extends person {
constructor(name, age, grade) {
super(name, age);
this.grade = grade;
}
speak() {
console.log(
"我叫",
this.name,
"我年龄是",
this.age,
"我上年纪",
this.age
);
}
study() {
// study 方法放在了--->类的原型对象上; 供实例使用
// 通过 student 实例调用时候, study 的 this 就是 student 实例
}
}
const s1 = new student("小白", 10, "六年级");
const s2 = new student("小黑", 11, "五年级");
s1.speak(); // 我叫 小白 我年龄是 10 我上年纪 10
console.log(s1); // student {name: '小白', age: 10, grade: '六年级'}
console.log(s2); // student {name: '小黑', age: 11, grade: '五年级'}
</script>
</body>
</html>
02-原生事件绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button id="btn1">按钮1</button>
<button id="btn2">按钮2</button>
<button id="btn3" onclick="demo3()">按钮3</button>
<script>
const btn1 = document.getElementById("btn1");
const btn2 = document.getElementById("btn2");
const btn3 = document.getElementById("btn3");
btn1.addEventListener("click", () => {
alert("点击了按钮1");
});
btn2.onclick = () => {
alert("点击了按钮2");
};
function demo3(params) {
alert("点击了按钮3");
}
</script>
</body>
</html>
03-类中方法 this 的指向
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script type="text/javascript">
class person {
constructor(name, age) {
this.name = name;
this.age = age;
}
speak() {
console.log(this);
}
}
const p1 = new person("tom", 18);
const x = p1.speak;
x(); // undefined
p1.speak(); // person {name: 'tom', age: 18}
// function demo(params) {
// "use strict"; // this就undefined了
// console.log(this); // window
// }
// demo();
</script>
</body>
</html>
04-展开运算符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
let arr1 = [1, 3];
let arr2 = [2, 4];
// 应用1:展开数组
console.log(...arr1); // 1 3
// 应用2: 连接数组
let arr3 = [...arr1, ...arr2];
console.log(arr3); // (4) [1, 3, 2, 4]
// 应用3: 配合函数使用
function sum(...numbers) {
console.log(numbers); // [1]
let sum = numbers.reduce((pre, cur) => {
return pre + cur;
}, 0);
return sum;
}
console.log(sum(1, 2, 3, 4, 5)); // 15
// 应用4: 构造字面量对象的时候使用展开语法
let person = { name: "123", value: "456" };
let person2 = { ...person }; // 这个写法 {...} 是ES6字面量形式,是被允许的
// console.log(...person2); // 展开运算符不能展开对象
console.log(person2); // {name: '123', value: '456'}
// 应用4: 合并对象
let person3 = { ...person, address: "999" };
console.log(person3); // {name: '123', value: '456', address: '999'}
</script>
</body>
</html>
05-高阶函数和函数柯里化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
/**
* 高阶函数: 如果一个函数符合下面两个规范中的任何一个,那么该函数就是高阶函数
* 1. 若A函数,接收的参数是一个函数,那么A函数就称为高阶函数
* 2. 若A函数,调用的返回值依然是一个函数,那么A函数就称为高阶函数
* 常见的高阶函数
* 1. Promise new Promise(()=>{})
* 2. setTimeout
* 3. arr.map 等等
*
*
* 函数的柯里化: 通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码方式
*/
// 1. 创建函数式组件
class MyComponent extends React.Component {
state = {
username: "",
password: "",
};
// 提交表单
handleSubmit = (event) => {
event.preventDefault(); // 可以阻止表单的默认跳转
const { username, password } = this.state;
console.log(username, password);
};
// 保存表单项的数据到状态中
saveFormData = (dataType) => {
return (event) => {
this.setState({ [dataType]: event.target.value });
};
};
render() {
return (
<form onSubmit={this.handleSubmit}>
用户名:{" "}
<input
onChange={this.saveFormData("username")}
type="text"
name="username"
/>
密码: <input
onChange={this.saveFormData("password")}
type="password"
password="password"
/>
<button>登录</button>
</form>
);
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
06-对象相关的知识
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
let a = "name";
let obj = {};
obj[a] = a;
</script>
</body>
</html>
07-演示函数柯里化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// function sum(a, b, c) {
// return a + b + c
// }
// const result = sum(1, 2, 3)
// 函数柯里化
function sum(a) {
return (b) => {
return (c) => {
return a + b + c;
};
};
}
const result = sum(1)(2)(3);
console.log(result);
</script>
</body>
</html>
React 入门
01-hello_react
demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01_hello_react</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建虚拟dom
const VDOM = <h1>01_hello_react</h1>; // 此处不写引号,因为是jsx可以混着写
// 2. 渲染虚拟dom到页面
ReactDOM.render(VDOM, document.getElementById("test"));
</script>
</body>
</html>
02-虚拟 dom 的两种创建方式
2.1-使用 js 创建虚拟 dom
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01_使用js创建虚拟dom</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/javascript">
// 1. 创建虚拟dom (使用这个方法仅限于简单的dom结构)
const VDOM = React.createElement(
"h1",
{ id: "title" },
React.createElement("span", {}, "01_使用js创建虚拟dom")
);
// 2. 渲染虚拟dom到页面
ReactDOM.render(VDOM, document.getElementById("test"));
</script>
</body>
</html>
2.2-使用 jsx 创建虚拟 dom
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>02_使用jsx创建虚拟dom</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建虚拟dom
const VDOM = (
<h1 id="title">
<span>02_使用jsx创建虚拟dom</span>
</h1>
); // 此处不写引号,因为是jsx可以混着写
// 2. 渲染虚拟dom到页面
ReactDOM.render(VDOM, document.getElementById("test"));
</script>
</body>
</html>
2.3-虚拟 DOM 和真实 DOM
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>03_虚拟DOM和真实DOM</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建虚拟dom
const VDOM = (
<h1 id="title">
<span>03_虚拟DOM和真实DOM</span>
</h1>
);
/**
* 1. VDOM本质就是 Object 对象
* 2. 虚拟DOM比较轻, 属性很少,虚拟DOM仅仅React内部使用,无需那么多的属性
* 3. 真实DOM比较重, 属性很多
* 4. 虚拟DOM最终会被React转为真实dom呈现到页面上
*/
console.log("虚拟DOM", VDOM); //虚拟DOM Object
const TDOM = document.getElementById("test");
console.log("真实DOM", TDOM); //真实DOM <div id="test"></div>
console.log(VDOM instanceof Object); // true
// 2. 渲染虚拟dom到页面
ReactDOM.render(VDOM, TDOM);
</script>
</body>
</html>
03-JSX
全名 JavaScript XML
3-1.JSX 语法规则
1. 定义虚拟 dom 的使用不要使用引号
2. 标签重混入 js 表达式的时候要用{}
一定要区分JS语句和JS表达式
1. 表达式: 一个表达式会产生一个值,可以放在任何一个需要值的地方
下面这些是表达式
1. a
2. a+b
3. demo(1)
4. arr.map()
5. function test(){}
2. 语句(代码)
下面这些是语句(代码)
1. if(){}
2. for(){}
3. switch(){}
3. 样式的类名不要用 class,要用 className
4. 内联样式要用 style={{}} 的形式,并且需要大驼峰 fontSize
5. 只能有一个根标签
6. 标签必须要闭合
7. 标签首字母
7.1 如果是小写字母开头,则就转为 html 的同名元素,如果没有对应的就会报错
7.2 如果是大写字母开头,React 就去渲染对应的组件,如果组件没有定义那么就报错
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>03_JSX语法规则</title>
<style>
.title {
width: 200px;
height: 200px;
background-color: yellow;
}
</style>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
/**
* JSX语法规则
* 1. 定义虚拟dom的使用不要使用引号
* 一定要区分JS语句和JS表达式
* 1. 表达式: 一个表达式会产生一个值,可以放在任何一个需要值的地方
* 下面这些是表达式
* 1. a
* 2. a+b
* 3. demo(1)
* 4. arr.map()
* 5. function test(){}
* 2. 语句(代码)
* 下面这些是语句(代码)
* 1. if(){}
* 2. for(){}
* 3. switch(){}
* 2. 标签重混入js表达式的时候要用{}
* 3. 样式的类名不要用class,要用className
* 4. 内联样式要用 style={{}} 的形式,并且需要大驼峰 fontSize
* 5. 只能有一个根标签
* 6. 标签必须要闭合
* 7. 标签首字母
* 7.1 如果是小写字母开头,则就转为html的同名元素,如果没有对应的就会报错
* 7.2 如果是大写字母开头,React就去渲染对应的组件,如果组件没有定义那么就报错
*/
const id = "id";
const data = "03_JSX语法规则";
// 1. 创建虚拟dom
const VDOM = (
<div>
<h1 id={id.toLowerCase()} className="title">
<span>{data.toLowerCase()}</span>
</h1>
<input type="text"></input>
</div>
);
// 2. 渲染虚拟dom到页面
ReactDOM.render(VDOM, document.getElementById("test"));
</script>
</body>
</html>
3-2.jsx 练习
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>jsx练习</title>
<style>
.title {
width: 200px;
height: 200px;
background-color: yellow;
}
</style>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
/**
* 一定要区分JS语句和JS表达式
* 1. 表达式: 一个表达式会产生一个值,可以放在任何一个需要值的地方
* 下面这些是表达式
* 1. a
* 2. a+b
* 3. demo(1)
* 4. arr.map()
* 5. function test(){}
* 2. 语句(代码)
* 下面这些是语句(代码)
* 1. if(){}
* 2. for(){}
* 3. switch(){}
*/
const data = ["angular", "react", "vue"];
const data2 = data.map((el) => <li key={el}>{el}</li>);
// 1. 创建虚拟dom
const VDOM = (
<div>
<h1>前端框架</h1>
<ul>{data2}</ul>
</div>
);
// 2. 渲染虚拟dom到页面
ReactDOM.render(VDOM, document.getElementById("test"));
</script>
</body>
</html>
React 面向组件编程
1-基本理解和使用
1.1-函数式组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建函数式组件
function MyComponent(params) {
console.log(this); // undefined ---> 是因为 babel 编译后是严格模式,那么this就不能指向window了,
return <h2>我是用函数定义的组件(适用于简单组件的定义)</h2>;
}
// 2. 渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test"));
/**
* 执行了 ReactDOM.render(<MyComponent />, document.getElementById("test"));
* 1. React会解析组件标签,找MyComponent组件
* 2. 发现组件是函数定义的,那么就调用这个函数,
* 3. 将返回的虚拟dom转换成真实dom.呈现在页面上
*/
</script>
</body>
</html>
1.2-类式组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 类式组件
class MyComponent extends React.Component {
render() {
// render 方法放在了--->类 MyComponent 的原型对象上; 供实例使用
// render 的this是谁 ---> MyComponent 的实例对象
console.log(this); // MyComponent {props: {…}, context: {…}, refs: {…}, updater: {…}, _reactInternalFiber: FiberNode, …}
return <h1>我是类定义的组件,适用于复杂组件</h1>;
}
}
// 2. 渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test"));
/**
* 执行了 ReactDOM.render(<MyComponent />, document.getElementById("test"));
* 1. React会解析组件标签,找MyComponent组件
* 2. 发现组件是函数定义的,那么就new出来该类的实例,并通过该实例调用到原型的render方法,
* 3. 将返回的虚拟dom转换成真实dom.呈现在页面上
*/
</script>
</body>
</html>
02-state
2.1-state 基础使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建组件
class Weather extends React.Component {
// constructor 构造器执行几次?-->new 几次就会执行几次
constructor(props) {
super(props);
// 初始化状态
this.state = {
isHot: true,
wind: "微风",
};
// 这样处理是为了解决静态方法内无法拿到类的this,解决this指向的问题
this.changeWeather = this.changeWeather.bind(this);
}
/**
* changeWeather放在哪里?---Watcher的原型对象上,供实例使用
* 由于changeWeather方法作为onClick的回调,所以不是实例调用的而是直接调用的
* 类中的方法默认开启了严格模式,所以changeWeather里面的this是undefined
*
*/
// changeWeather 执行几次?--->点几次调用几次
changeWeather() {
const isHot = this.state.isHot;
// state里面的状态里面的数据要修改需要使用 setState 方法
// this.state.isHot = !isHot // 错误的写法
this.setState({
isHot: !isHot,
});
}
// render 执行几次?--> 执行 n+1 次, n 是状态更新的次数,每次 state 更新, render 都会执行
render() {
// 读取状态
const { isHot, wind } = this.state;
return (
<div>
<button onClick={this.changeWeather}>改变天气</button>
<h1>
今天的天气好: {isHot ? "热" : "冷"},{wind}
</h1>
</div>
);
}
}
// 2. 渲染组件到页面
ReactDOM.render(<Weather />, document.getElementById("test"));
</script>
</body>
</html>
2.2-state 简写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
class Weather extends React.Component {
// 初始化状态
state = { isHot: true, wind: "微风" };
/**
* 自定义方法:---以后都成 赋值语句的形式+箭头函数
* this执行就会到了watcher了
* 这样的写法就是把 changeWeather 放在自身,而不是放在原型函数上
*/
changeWeather = () => {
console.log(this); // Weather {props: {…}, context: {…}, refs: {…}, updater: {…}, state: {…}, …}
const isHot = this.state.isHot;
this.setState({ isHot: !isHot });
};
render() {
const { isHot, wind } = this.state;
return (
<div>
<h1 onClick={this.changeWeather}>
今天的天气好: {isHot ? "热" : "冷"},{wind}
</h1>
</div>
);
}
}
// 2. 渲染组件到页面
ReactDOM.render(<Weather />, document.getElementById("test"));
</script>
</body>
</html>
03-props
3.1-props 基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建函数式组件
class MyComponent extends React.Component {
render() {
return (
<ul>
<li>姓名{this.props.name}</li>
<li>年龄{this.props.age}</li>
<li>性别{this.props.sex}</li>
</ul>
);
}
}
// 2. 渲染组件到页面
ReactDOM.render(
<MyComponent name="tom" age="12" sex="男" />,
document.getElementById("test")
);
</script>
</body>
</html>
3.2-对 props 进行限制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 引入prop-types,用于对组件标签属性进行限制 -->
<script src="../React-js/prop-types.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建函数式组件
class MyComponent extends React.Component {
// props是只读的
render() {
return (
<ul>
<li>姓名{this.props.name}</li>
<li>年龄{this.props.age}</li>
<li>性别{this.props.sex}</li>
</ul>
);
}
}
// 对标签属性进行必要性的限制
MyComponent.propTypes = {
name: PropTypes.string.isRequired, // 限制姓名为字符串且必填
name: PropTypes.string, // 限制必须字符串
age: PropTypes.number, // 限制必须数字
speak: PropTypes.func, // 限制必须为函数
};
// 指定属性的默认值
MyComponent.defaultProps = {
sex: "不男不女",
age: 18,
};
const info = { name: "123", age: 13 };
ReactDOM.render(
<MyComponent {...info} speak={speak} />,
document.getElementById("test1")
);
function speak(params) {
console.log("我说话了");
}
</script>
</body>
</html>
3.3-props 简写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 引入prop-types,用于对组件标签属性进行限制 -->
<script src="../React-js/prop-types.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建函数式组件
class MyComponent extends React.Component {
// 对标签属性进行必要性的限制
static propTypes = {
name: PropTypes.string.isRequired, // 限制姓名为字符串且必填
name: PropTypes.string, // 限制必须字符串
age: PropTypes.number, // 限制必须数字
speak: PropTypes.func, // 限制必须为函数
};
// 指定属性的默认值
static defaultProps = {
sex: "不男不女",
age: 18,
};
// props是只读的
render() {
return (
<ul>
<li>姓名{this.props.name}</li>
<li>年龄{this.props.age}</li>
<li>性别{this.props.sex}</li>
</ul>
);
}
}
const info = { name: "123", age: 13 };
ReactDOM.render(
<MyComponent {...info} speak={speak} />,
document.getElementById("test1")
);
function speak(params) {
console.log("我说话了");
}
</script>
</body>
</html>
3.4-props 在构造函数中情况
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 引入prop-types,用于对组件标签属性进行限制 -->
<script src="../React-js/prop-types.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建函数式组件
class MyComponent extends React.Component {
// props是只读的
render() {
return (
<ul>
<li>姓名{this.props.name}</li>
<li>年龄{this.props.age}</li>
<li>性别{this.props.sex}</li>
</ul>
);
}
}
const info = { name: "123", age: 13 };
ReactDOM.render(
<MyComponent {...info} speak={speak} />,
document.getElementById("test1")
);
function speak(params) {
console.log("我说话了");
}
</script>
</body>
</html>
3.5-props 在函数值组件中使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 引入prop-types,用于对组件标签属性进行限制 -->
<script src="../React-js/prop-types.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建函数式组件
function MyComponent(props) {
const { name, age, sex } = props;
return (
<ul>
<li>姓名{name}</li>
<li>年龄{age}</li>
<li>性别{sex}</li>
</ul>
);
}
// 对标签属性进行必要性的限制
MyComponent.propTypes = {
name: PropTypes.string.isRequired, // 限制姓名为字符串且必填
name: PropTypes.string, // 限制必须字符串
age: PropTypes.number, // 限制必须数字
speak: PropTypes.func, // 限制必须为函数
};
// 指定属性的默认值
MyComponent.defaultProps = {
sex: "不男不女",
age: 18,
};
const info = { name: "123", age: 13 };
ReactDOM.render(
<MyComponent {...info} />,
document.getElementById("test1")
);
</script>
</body>
</html>
04-refs
4.1-字符串形式 refs 的基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
/**
* 字符串的refs存在效率上的问题,不推荐使用
*/
// 1. 创建函数式组件
class MyComponent extends React.Component {
// 展示左侧输入框的数据
showData = () => {
const { input1 } = this.refs;
let value1 = input1.value;
console.log(value1);
};
// 展示右侧输入框的数据
showData2 = () => {
const { input2 } = this.refs;
let value2 = input2.value;
console.log(value2);
};
render() {
return (
<div>
<input
ref="input1"
type="text"
placeholder="点击按钮提示数据"
></input>
<button onClick={this.showData}>点我提示左侧的数据</button>
<input
ref="input2"
onBlur={this.showData2}
type="text"
placeholder="失去焦点提示数据"
></input>
</div>
);
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
4.2-回调形式 refs 的基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
/**
* 字符串的refs存在效率上的问题,不推荐使用
*/
// 1. 创建函数式组件
class MyComponent extends React.Component {
// 展示左侧输入框的数据
showData = () => {
const { input1 } = this;
let value1 = input1.value;
alert(value1);
};
// 展示右侧输入框的数据
showData2 = () => {
const { input2 } = this;
let value2 = input2.value;
alert(value2);
};
render() {
return (
<div>
<input
ref={(c) => (this.input1 = c)}
type="text"
placeholder="点击按钮提示数据"
></input>
<button onClick={this.showData}>点我提示左侧的数据</button>
<input
ref={(c) => (this.input2 = c)}
onBlur={this.showData2}
type="text"
placeholder="失去焦点提示数据"
></input>
</div>
);
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
4.3-回调形式 refs 的回调执行次数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
/**
* 字符串的refs存在效率上的问题,不推荐使用
*/
// 1. 创建函数式组件
class MyComponent extends React.Component {
state = { isHot: true };
// 展示左侧输入框的数据
showData = () => {
const { input1 } = this;
let value1 = input1.value;
alert(value1);
};
changeWeather = () => {
const { isHot } = this.state;
this.setState({
isHot: !isHot,
});
};
saveInput = (c) => {
this.input1 = c;
console.log(c);
};
render() {
const { isHot } = this.state;
return (
<div>
<h2>今天天气很{isHot ? "热" : "冷"}</h2>
{/*这种写法有个问题,就是更新时候,这个console.log(c)会执行两次,第一次c是null,第二才是这个dom结构*/}
{/*<input ref={c => { this.input1 = c; console.log(c); }} type="text" placeholder="点击按钮提示数据"></input>*/}
{/*这种写法是做好的,只会执行一次,但是没必要*/}
<input
ref={this.saveInput}
type="text"
placeholder="点击按钮提示数据"
></input>
<button onClick={this.showData}>点我提示左侧的数据</button>
<button onClick={this.changeWeather}>点我切换天气</button>
</div>
);
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
4.4-createRef 形式 refs 的基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建函数式组件
class MyComponent extends React.Component {
/**
* React.createRef调用后返回䘝容器,该容器可以存储被ref所标识的节点
* 该容器是专人专用,只能存一个节点
*/
myRef1 = React.createRef();
myRef2 = React.createRef();
// 展示左侧输入框的数据
showData = () => {
alert(this.myRef1.current.value);
};
// 展示右侧输入框的数据
showData2 = () => {
alert(this.myRef2.current.value);
};
render() {
return (
<div>
<input
ref={this.myRef1}
type="text"
placeholder="点击按钮提示数据"
></input>
<button onClick={this.showData}>点我提示左侧的数据</button>
<input
ref={this.myRef2}
onBlur={this.showData2}
type="text"
placeholder="失去焦点提示数据"
></input>
</div>
);
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
4.5-.事件处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建函数式组件
class MyComponent extends React.Component {
/**
* 1. 通过 onXxx 属性指定事件处理函数(注意大小写)
* 1.1 React 使用的是自定义(合成)事件,而不是使用的原生DOM的事件 --- 为了更好的兼容性
* 1.2 React 中的事件是通过事件委托方式处理的(委托给组件的最外层) --- 为了高效
* 2. 通过 event.target 得到发生事件的 DOM 元素 --- 不要过度使用 ref
*/
//创建ref容器
myRef1 = React.createRef();
// 展示左侧输入框的数据
showData = () => {
alert(this.myRef1.current.value);
};
// 展示右侧输入框的数据
showData2 = (event) => {
alert(event.target.value);
};
render() {
return (
<div>
<input
ref={this.myRef1}
type="text"
placeholder="点击按钮提示数据"
></input>
<button onClick={this.showData}>点我提示左侧的数据</button>
<input
onBlur={this.showData2}
type="text"
placeholder="失去焦点提示数据"
></input>
</div>
);
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
5-React 中收集表单数据
5.1-非受控组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建函数式组件
class MyComponent extends React.Component {
handleSubmit = (e) => {
const { username, password } = this;
e.preventDefault(); // 可以阻止表单的默认跳转
console.log(username.value, password.value);
};
render() {
return (
<form onSubmit={this.handleSubmit}>
用户名:{" "}
<input
ref={(c) => (this.username = c)}
type="text"
name="username"
/>
密码: <input
ref={(c) => (this.password = c)}
type="password"
password="password"
/>
<button>登录</button>
</form>
);
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
5.2-受控组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
/**
* 手控组件的好处就是省掉了过多的ref
*/
// 1. 创建函数式组件
class MyComponent extends React.Component {
state = {
username: "",
password: "",
};
handleSubmit = (e) => {
e.preventDefault(); // 可以阻止表单的默认跳转
const { username, password } = this.state;
console.log(username, password);
};
// 保存用户名到state
changeUsername = (e) => {
this.setState({ username: e.target.value });
};
// 保存密码到state
changePassword = (e) => {
this.setState({ password: e.target.value });
};
render() {
return (
<form onSubmit={this.handleSubmit}>
用户名:{" "}
<input
onChange={this.changeUsername}
type="text"
name="username"
/>
密码: <input
onChange={this.changePassword}
type="password"
password="password"
/>
<button>登录</button>
</form>
);
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
6-高阶函数与函数柯里化
6.1-高阶函数和函数柯里化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
/**
* 高阶函数: 如果一个函数符合下面两个规范中的任何一个,那么该函数就是高阶函数
* 1. 若A函数,接收的参数是一个函数,那么A函数就称为高阶函数
* 2. 若A函数,调用的返回值依然是一个函数,那么A函数就称为高阶函数
* 常见的高阶函数
* 1. Promise new Promise(()=>{})
* 2. setTimeout
* 3. arr.map 等等
*
*
* 函数的柯里化: 通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码方式
*/
// 1. 创建函数式组件
class MyComponent extends React.Component {
state = {
username: "",
password: "",
};
// 提交表单
handleSubmit = (event) => {
event.preventDefault(); // 可以阻止表单的默认跳转
const { username, password } = this.state;
console.log(username, password);
};
// 保存表单项的数据到状态中
saveFormData = (dataType) => {
return (event) => {
this.setState({ [dataType]: event.target.value });
};
};
render() {
return (
<form onSubmit={this.handleSubmit}>
用户名:{" "}
<input
onChange={this.saveFormData("username")}
type="text"
name="username"
/>
密码: <input
onChange={this.saveFormData("password")}
type="password"
password="password"
/>
<button>登录</button>
</form>
);
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
6.2-不用高阶函数和函数柯里化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 1. 创建函数式组件
class MyComponent extends React.Component {
state = {
username: "",
password: "",
};
// 提交表单
handleSubmit = (event) => {
event.preventDefault(); // 可以阻止表单的默认跳转
const { username, password } = this.state;
console.log(username, password);
};
// 保存表单项的数据到状态中
saveFormData = (dataType, event) => {
this.setState({ [dataType]: event.target.value });
};
render() {
return (
<form onSubmit={this.handleSubmit}>
用户名:{" "}
<input
onChange={(event) => {
this.saveFormData("username", event);
}}
type="text"
name="username"
/>
密码: <input
onChange={(event) => {
this.saveFormData("password", event);
}}
type="password"
password="password"
/>
<button>登录</button>
</form>
);
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
7-组件的生命周期
7-1.引出生命周期
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test"></div>
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 生命周期回调函数 === 生命周期钩子函数 === 生周期函数 === 生命周期钩子
// 1. 创建函数式组件
class MyComponent extends React.Component {
state = { opacity: 1 };
death = () => {
// 卸载组件
ReactDOM.unmountComponentAtNode(document.getElementById("test1"));
};
// 组件挂在完毕时候调用
componentDidMount() {
this.timer = setInterval(() => {
let { opacity } = this.state;
opacity -= 0.1;
if (opacity <= 0) {
opacity = 1;
}
this.setState({ opacity });
}, 200);
}
// 组件将要卸载时候调用
componentWillUnmount() {
clearInterval(this.timer);
}
// 初始化渲染, 状态更新之后
render() {
return (
<div>
<h2 style={{ opacity: this.state.opacity }}>
React学不会怎么办?
</h2>
<button onClick={this.death}>不活了!</button>
</div>
);
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
7-2.生命周期-挂载(旧)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 生命周期回调函数 === 生命周期钩子函数 === 生周期函数 === 生命周期钩子
// 1. 创建函数式组件
class MyComponent extends React.Component {
// 构造器 (第一步)
constructor(props) {
super(props);
// 初始化状态
this.state = { count: 0 };
console.log("挂载 第一步--->constructor");
}
death = () => {
ReactDOM.unmountComponentAtNode(document.getElementById("test1"));
};
// 组件将要挂载时候调用 (第二步)
componentWillMount() {
console.log("挂载 第二步--->componentWillMount");
}
// 初始化渲染, 状态更新之后
render() {
console.log("挂载 第三步--->render");
return (
<div>
<h2>当前求和为: {this.state.count}</h2>
<button onClick={this.death}>卸载组件</button>
</div>
);
}
// 组件挂载完毕时候调用
componentDidMount() {
console.log("挂载 第四步--->componentDidMount");
}
// 组件将要卸载时候调用
componentWillUnmount() {
console.log("挂载 第五步--->componentWillUnmount");
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
7-3.生命周期-setState 更新(旧)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 生命周期回调函数 === 生命周期钩子函数 === 生周期函数 === 生命周期钩子
// 1. 创建函数式组件
class MyComponent extends React.Component {
// 构造器 (第一步)
constructor(props) {
super(props);
// 初始化状态
this.state = { count: 0 };
}
add = () => {
const { count } = this.state;
this.setState({
count: count + 1,
});
console.log("更新 第一步--->setState");
};
// 控制组件更新的开关
shouldComponentUpdate() {
console.log("更新 第二步--->shouldComponentUpdate");
return true;
}
componentWillUpdate() {
console.log("更新 第三步--->componentWillUpdate");
}
// 初始化渲染, 状态更新之后
render() {
console.log("更新 第四步--->render");
return (
<div>
<h2>当前求和为: {this.state.count}</h2>
<button onClick={this.add}>点我+1</button>
</div>
);
}
componentDidUpdate() {
console.log("更新 第五步--->componentDidUpdate");
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
7-4.生命周期-forceUpdate 更新(旧)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 生命周期回调函数 === 生命周期钩子函数 === 生周期函数 === 生命周期钩子
// 1. 创建函数式组件
class MyComponent extends React.Component {
// 构造器 (第一步)
constructor(props) {
super(props);
// 初始化状态
this.state = { count: 0 };
}
// 强制更新按钮(不会走到shouldComponentUpdate)
force = () => {
this.forceUpdate();
console.log("更新 第一步--->forceUpdate");
};
componentWillUpdate() {
console.log("更新 第二步--->componentWillUpdate");
}
// 初始化渲染, 状态更新之后
render() {
console.log("更新 第三步--->render");
return (
<div>
<h2>当前求和为: {this.state.count}</h2>
<button onClick={this.force}>不更新数据强制更新页面</button>
</div>
);
}
componentDidUpdate() {
console.log("更新 第四步--->componentDidUpdate");
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>
7-5.生命周期-父组件 render 更新(旧)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 生命周期回调函数 === 生命周期钩子函数 === 生周期函数 === 生命周期钩子
// 父组件A
class A extends React.Component {
state = { carName: "奔驰" };
changeCar = () => {
this.setState({ carName: "奥迪" });
};
render() {
return (
<div>
<h1>A</h1>
<button onClick={this.changeCar}>换车</button>
<B carName={this.state.carName} />
</div>
);
}
}
// 子组件B
class B extends React.Component {
// 这个钩子第一次传的不算
componentWillReceiveProps(props) {
console.log("子组件更新 第一步--->componentWillReceiveProps");
console.log(props);
}
// 控制组件更新的开关
shouldComponentUpdate() {
console.log("子组件更新 第二步--->shouldComponentUpdate");
return true;
}
componentWillUpdate() {
console.log("子组件更新 第三步--->componentWillUpdate");
}
render() {
console.log("子组件更新 第四步--->render");
return <div>B -- {this.props.carName}</div>;
}
componentDidUpdate() {
console.log("子组件更新 第五步--->componentDidUpdate");
}
}
// 2.渲染组件到页面
ReactDOM.render(<A />, document.getElementById("test1"));
</script>
</body>
</html>
7-6.生命周期总结(旧)
/**
* 常用:
* 1. componentDidMount() 一般做一些初始化的事儿,例如开始定制器或者发送网络请求或者订阅消息
* 2. componentWillUnmount() 一般做一些收尾的事儿,例如取消定时器
*
* 1. 初始化阶段: 由 ReactDOM.render() 触发---初次渲染
* 1. constructor()
* 2. componentWillMount()
* 3. render()
* 4. componentDidMount()
* 2. 更新阶段: 由组件内部 setState() 或者父组件 render() 触发
* 1. shouldComponentUpdate()
* 2. componentWillUpdate()
* 3. render()
* 4. componentDidMount()
* 3. 更新阶段: 由组件内部 forceUpdate() 触发
* 1. componentWillUpdate()
* 2. render()
* 3. componentDidMount()
* 4. 父组件Props更新: 由父组件Props更新导致子组件更新
* 1. componentWillReceiveProps()
* 2. shouldComponentUpdate()
* 3. componentWillUpdate()
* 4. render()
* 5. componentDidMount()
* 5. 卸载组件: 由 ReactDOM.unmountComponentAtNode() 触发
* 1. componentWillUnmount()
*/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>01-函数式组件</title>
</head>
<body>
<!-- 准备好容器 -->
<div id="test1"></div>
<!-- 引入React核心库. -->
<script src="../React-js/react.development.js"></script>
<!-- 引入React-dom,用于支持操作DOM -->
<script src="../React-js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="../React-js/babel.min.js"></script>
<!-- 写这个type的意义是为了让他知道我写的是jsx -->
<script type="text/babel">
// 生命周期回调函数 === 生命周期钩子函数 === 生周期函数 === 生命周期钩子
// 1. 创建函数式组件
class MyComponent extends React.Component {
// 构造器 (第一步)
constructor(props) {
super(props);
// 初始化状态
this.state = { count: 0 };
console.log("挂载 第一步--->constructor");
}
death = () => {
ReactDOM.unmountComponentAtNode(document.getElementById("test1"));
};
// 组件将要挂载时候调用 (第二步)
componentWillMount() {
console.log("挂载 第二步--->componentWillMount");
}
// 初始化渲染, 状态更新之后
render() {
console.log("挂载 第三步--->render");
return (
<div>
<h2>当前求和为: {this.state.count}</h2>
<button onClick={this.death}>卸载组件</button>
</div>
);
}
// 组件挂载完毕时候调用
componentDidMount() {
console.log("挂载 第四步--->componentDidMount");
}
// 组件将要卸载时候调用
componentWillUnmount() {
console.log("挂载 第五步--->componentWillUnmount");
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById("test1"));
</script>
</body>
</html>