1 Basic understanding and use
Functional components
<!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>1_函数式组件</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="../js/react.development.js"></script>
<!-- 引入react-from,用于支持react操作dom -->
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
// 1. 创建函数式组件
function MyComponent() {
console.log(this); // 此处的this是undefined,因为babel编译后开启了严格模式
return <h2>我使用函数定义的组件(适用于【简单组件】的定义)</h2>;
}
// 2. 渲染组件到页面
ReactDOM.render(<MyComponent/>, document.getElementById('test'));
/*
执行了React.render(<MyComponent/>.......之后发生了什么)
1. react会解析组件标签,找到了Mycomponent组件。发现组件是使用函数定义的,随后调用该函数,将返回的虚拟Dom转为真实Dom,随后呈现在页面中
*/
</script>
</body>
</html>
class component
<!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>2_类式组件</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="../js/react.development.js"></script>
<!-- 引入react-from,用于支持react操作dom -->
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
// 1.创建类式组件
class MyComponent extends React.Component{
render() {
// render方法放在了哪里? --- MyComponent的原型对象上,供实例使用
// render中的this是谁? --- MyComponent的实例对象 MyComponent组件的实例对象
console.log('render中的this', this);
return <h2>我使用类定义的组件(适用于【复杂组件】的定义)</h2>;
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent/>, document.getElementById('test'));
/*
执行了React.render(<MyComponent/>.......之后发生了什么)
1. react会解析组件标签,找到了Mycomponent组件。
2.发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法
3.将render返回的虚拟DOM转为真实DOM,随后呈现在页面中
*/
</script>
</body>
</html>
Notice
-
Component names must first be capitalized
-
Virtual DOM elements can only have one root element
-
Virtual DOM elements must have closing tags
class review
<!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>1_类的基本知识</title>
</head>
<body>
<script type="text/javascript">
/*
总结:
1.类中的构造器不是必须写的,要对实例进行一些初始化的操作,如添加指定属性时,才写
2.如果A类继承了B类,且A类写了构造器,那么A类构造器中super是必须要调用的。
3.类中所定义的方法,都是放在了类的原型对象上,供实例使用
*/
// 创建一个Person类
class Person {
// 构造器方法
constructor(name, age) {
// 构造器中的this是谁?--类的实例对象
this.name = name;
this.age = age;
}
// 一般方法
speak() {
// speak方法放在了哪里? --- 类的原型对象上,供实例使用
// 通过Person实例调用speak时,speak中的this就是Person实例
console.log(`我叫${
this.name},我年龄是${
this.age}`);
}
}
// 创建一个student类,继承于Person类
class Student extends Person {
constructor(name, age, grade) {
super(name, age);
this.grade = grade;
}
// 重写从父类继承过来的方法
speak() {
console.log(`我叫${
this.name},我年龄时${
this.age},我读的是${
this.grade}年级`);
}
study() {
// study方法放在了哪里? --- 类的原型对象上,供实例使用
// 通过Student实例调用study时,study中的this就是Student实例
console.log('我很努力的学习');
}
}
// 创建一个Person的实例对象
// const p1 = new Person('tom', 18);
// const p2 = new Person('jerry', 19);
// console.log(p1);
// console.log(p2);
// p1.speak();
// p2.speak();
// p1.speak.call({a: 1, b: 2});
const s1 = new Student('小张', 15, '高一');
console.log(s1);
s1.speak();
s1.study();
</script>
</body>
</html>
2 Three core attributes of component instances 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>state.html</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="../js/react.development.js"></script>
<!-- 引入react-from,用于支持react操作dom -->
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
// 1.创建组件
class Weather extends React.Component {
constructor(props) {
super(props);
this.state = {
isHot: true}
}
render() {
// 读取状态
const {
isHot} = this.state;
return <h1 onClick={
demo}>今天天气很{
isHot ? '炎热' : '凉爽'}</h1>
}
}
// 2.渲染组件到页面
ReactDOM.render(<Weather/>, document.getElementById('test'));
function demo() {
alert('按钮3被点击了');
}
</script>
</body>
</html>
2.1 Exercise
Requirement: Define a component that displays weather information
1. The default display is hot or cool
2. Click on the text to switch weather
<!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>state.html</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="../js/react.development.js"></script>
<!-- 引入react-from,用于支持react操作dom -->
<script
type="text/javascript"
src="../js/react-dom.development.js"
></script>
<!-- 引入babel,用于将jsx转为js -->
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
// 1.创建组件
class Weather extends React.Component {
// 构造器调用几次?-----1次
constructor(props) {
super(props);
// 初始化状态
this.state = {
isHot: true, wind: '微风' };
// 解决changeWeacther中this指向问题
this.changeWeather = this.changeWeather.bind(this);
}
// render调用几次?----- 点几次调用几次
render() {
// 读取状态
const {
isHot, wind } = this.state;
return (
<h1 onClick={
this.changeWeather}>今天天气很{
isHot ? "炎热" : "凉爽"}, {
wind}</h1>
);
}
// changeWeather调用几次?----- 点几次调用几次
changeWeather() {
// changeWeather方法放在了哪里? --- Weather的原型对象上,供实例使用
// 由于changeWeather是作为onClick的回调,所以不是通过实例调用,是直接调用
// 类中的方法默认开启了局部的严格模式,所以changeWeather中的this位undefined
// 获取原来的isHot值
const isHot = this.state.isHot;
// 严重注意:状态必须通过setState进行更新,更新是一种合并,不是替换
this.setState({
isHot: !isHot})
// 严重注意:状态(state)不可以直接更改,下面这行就是直接更改
// this.state.isHit = !isHot; // 错误写法
}
}
// 2.渲染组件到页面
ReactDOM.render(<Weather />, document.getElementById("test"));
</script>
</body>
</html>
abbreviation
<!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>state.html</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="../js/react.development.js"></script>
<!-- 引入react-from,用于支持react操作dom -->
<script
type="text/javascript"
src="../js/react-dom.development.js"
></script>
<!-- 引入babel,用于将jsx转为js -->
<script type="text/javascript" src="../js/babel.min.js"></script>
<script type="text/babel">
class Weather extends React.Component {
state = {
isHot: true, wind: '微风' };
render() {
// 读取状态
const {
isHot, wind } = this.state;
return (
<h1 onClick={
this.changeWeather}>今天天气很{
isHot ? "炎热" : "凉爽"}, {
wind}</h1>
);
}
// 自定义方法-----要用赋值语句形式 + 箭头函数
changeWeather = () => {
const isHot = this.state.isHot;
this.setState({
isHot: !isHot})
}
}
ReactDOM.render(<Weather />, document.getElementById("test"));
</script>
</body>
</html>
2.2 Understanding
-
State is the most important attribute of the component object, and the value is the object (can contain multiple key-value combinations)
-
Components are called "state machines", and the corresponding page display is updated by updating the component's state (re-rendering the component)
2.3 Strong attention
-
This in the render method of the component is the component instance object
-
This is undefined in the component's custom method. How to solve it?
a) Forcibly bind this: through bind() of the function object
b) arrow function
-
Status data cannot be modified or updated directly
3 Three core attributes of components 2: props
函数式组件能用props,但是不能用state,refs
3.1 Effect
Requirements Customize the component used to display a person's information
1. The name must be specified and is of string type;
2. Gender is a string type. If gender is not specified, it defaults to male
3. The age is a string type and a numeric type. The default value is 18
3.2 Understanding
-
Each component object will have props (abbreviation for properties) attributes
-
All properties of component tags are saved in props
3.3 Function
-
Pass changing data from outside the component to within the component through label attributes
-
Note: Do not modify props data inside the component
3.4 Encoding operation
-
Read an attribute value internally
this.props.name
-
Type restrictions and necessity restrictions on attribute values in props
The first way (deprecated since React v15.5):
Person.propTypes = {
name: React.PropTypes.string.isRequired,
age: React.PropTypes.number
}
The second way (new): use prop-types library to impose restrictions (prop-types library needs to be introduced)
Person.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number
}
- Extended properties: Pass all properties of the object through props
<Person {
...person}/>
- Default property values:
Person.defaultProps = {
age: 18,
sex:'男'
}
-
Constructor of component class
constructor(props){ super(props) console.log(props)//打印所有属性 }
props
It is read-only and cannot be modified.
eg:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hello_react</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test1"></div>
<div id="test2"></div>
<div id="test3"></div>
<!-- 引入react核心库 -->
<script type="text/javascript" src="../js/react.development.js"></script>
<!-- 引入react-from,用于支持react操作dom -->
<script type="text/javascript" src="../js/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script type="text/javascript" src="../js/babel.min.js"></script>
<!-- 引入prop-types,用于对组件标签属性进行限制 -->
<script type="text/javascript" src="../js/prop-types.js"></script>
<script type="text/babel"> /* 此处一定要写babel */
// 创建组件
class Person extends React.Component {
state = {
name: 'tom', age: 18, sex: '女'};
render() {
console.log(this);
const {
name, age, sex} = this.props;
// props是只读的
this.props.name = 'jack'; // 此行代码会报错,因为props是只读的
return (
<ul>
<li>姓名:{
name}</li>
<li>性别:{
sex}</li>
<li>年龄:{
age + 1}</li>
</ul>
)
}
}
// 对标签属性进行类型、必要性限制
Person.propTypes = {
name: PropTypes.string.isRequired, // 限制name必传,且为字符串
sex: PropTypes.string, // 限制name为字符串
age: PropTypes.number, // 限制age为数值
speak: PropTypes.func, // 限制speak为函数
}
// 只当默认标签属性值
Person.defaultProps = {
sex: '不男不女', // sex默认值为男
age: 18 // sex默认值为男
}
// 渲染组件到页面
ReactDOM.render(<Person name="jerry" speak="1"/>, document.getElementById('test1'));
ReactDOM.render(<Person name="tom" age={
18} sex="男"/>, document.getElementById('test2'));
const p = {
name: '老刘', age: 18, sex: '女'};
console.log(...p);
// ReactDOM.render(<Person name={p.name} age={p.age} sex={p.sex}/>, document.getElementById('test3'));
ReactDOM.render(<Person {
...p}/>, document.getElementById('test3'));
function speak() {
console.log('我说话了');
}
</script>
</body>
</html>
4 Three core attributes of components 3: refs and event processing
practise
Requirements: Custom components, the function description is as follows:
-
Click the button to prompt for the value in the first input box
-
When the second input box loses focus, prompt the value in this input box
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>4_createRef</title> </head> <body> <!-- 准备好一个容器 --> <div id="test"></div> <!-- 引入react核心库 --> <script type="text/javascript" src="../js/react.development.js"></script> <!-- 引入react-from,用于支持react操作dom --> <script type="text/javascript" src="../js/react-dom.development.js" ></script> <!-- 引入babel,用于将jsx转为js --> <script type="text/javascript" src="../js/babel.min.js"></script> <script type="text/babel"> // 创建组件 class Demo extends React.Component { /* React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点,该容器是“专人专用”的 */ myRef = React.createRef(); myRef2 = React.createRef(); // 展示左侧输入框的数据 showData = () => { alert(this.myRef.current.value); }; showData2 = () => { alert(this.myRef2.current.value); } render() { return ( <div> <input ref={ this.myRef} type="text" placeholder="点击按钮提示数据" /> <button onClick={ this.showData}> 点我提示左侧的数据 </button> <input onBlur={ this.showData2} ref={ this.myRef2} type="text" placeholder="失去焦点提示数据" /> </div> ); } } // 渲染组件到页面 ReactDOM.render(<Demo />, document.getElementById("test")); </script> </body> </html>
understand
Tags within components can define ref attributes to identify themselves.
coding
- ref in string form
<input ref="input1"/>
- ref in callback form
<input ref={(c)=>{this.input1 = c}}
- createRef creates a ref container
myRef = React.createRef()
<input ref={this.myRef}/>
event handling
-
Specify the event processing function through the onXxx attribute (note the case)
-
React uses custom (synthetic) events instead of native DOM events ---- for better compatibility
-
Events in React are handled through event delegation (delegated to the outermost element of the component) ----- For efficiency
-
-
Get the DOM element object where the event occurred through event.target ----- Don't overuse ref