学习视频:尚硅谷React技术全家桶全套完整版(零基础入门到精通/男神天禹老师亲授)_哔哩哔哩_bilibili
注意点:
(1)函数名的首字母一定要大写。【这个涉及到上一节的 jsx 语法规则,若首字母是小写字母,则会被识别为对应的html标签;若首字母是大写字母,才会去找对应的组件。】
(2)标签名一定要闭合。
执行ReactDOM.render(...)之后,发生了什么?
(1)React 解析组件标签,找到 Demo 组件。
(2)发现组件是使用函数定义的,随后调用该函数,将返回的虚拟 DOM 转为真实 DOM 呈现到页面中。
注意点:
(1)类式组件必须继承 React.Component 。
(2)一定要理解清楚代码注释中的两大问题:
① 类中的方法是放在哪儿的?
② 方法中的this是什么?
执行了ReactDOM.render(
.......)之后,发生了什么?
(1)React 解析组件标签,找到了 MyComponent 组件。
(2)发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法。【所以 render 中的 this 是组件实例对象!】
(3)将 render 返回的虚拟 DOM 转为真实 DOM,随后呈现在页面中。
2.1.1 理解
2.1.2 通过实际案例来理解
实现效果:在控制台通过点击实现“炎热”和“凉爽”的交替变化。
这部分可以参考学习视频,老师是一步步递进的,讲的很不错。
注意点:
(1)state 是一个对象,不是一个数组。
(2)状态必须通过 setState({}) 来进行更新。
(3)关于绑定事件,React 将 onclick => onClick,并且绑定事件必须要返回函数,不能返回表达式。
关于 this 的指向问题:
(1)毫无疑问 constructor 当中的 this 就是 Demo 实例。
(2)render 的 this 也是 Demo 实例,因为 React 渲染组件到页面时,给我们 new 了一个实例,并且通过该实例去调用 render 方法。
(3)changeWeather 是我们自定义的方法,当中的 this 是 undefined 。首先,我们不是通过实例对象去调用的方法,因此无法指向实例对象。其次,因为在类中默认开启了严格模式,因此也无法指向 window。
如何解决 this 指向问题:
(1)强制绑定 this:通过函数对象的bind() 。
(2)使用箭头函数:原因是箭头函数没有自己的 this,导致内部的 this 就是外层代码块的 this。(具体实现在后面的简化 code 中)
注意点:
(1)我们将 state 用赋值语句定义实例属性,这个实例属性只能在内部进行使用,如果需要外界实例给定参数,则依旧需要定义构造器初始化参数。
(2) 使用箭头函数自定义方法,由于箭头函数没有 this,因此方法中的 this 指向的是外层代码块的 this,也就是这里的实例对象。
2.2.1 概念
理解:
每个组件对象都会有 props ( properties 的简写 ) 属性。
组件标签的所有属性都保存在props中。
作用:
- 通过标签属性从组件外向组件内传递变化的数据。
- 注意:组件内部不要修改props数据。
2.2.2 实际案例
实现效果:在控制台展示数据。
code:
注意点:
(1)可以通过在组件上定义属性传入参数。
// 第一种写法:直接写标签属性。 ReactDOM.render(
, document.querySelector('.box')); // 第二种写法:定义一个对象,通过...运算符解构对象。(原生js中...是无法解构对象的,这里只是一种固定的写法) const per = { name: '张三', age: 18, sex: '男' }; ReactDOM.render( , document.querySelector('.box')); (2)static 定义静态属性。
静态属性指的是 Class 本身的属性,即 Class.propname,而不是定义在实例对象 ( this ) 上的属性。
以上 code 定义了两个静态属性,[ 设置类型、必要性限制的 propTypes ] 与 [ 设置标签默认值属性的 defaultProps ]。
// 对标签属性进行类型、必要性的限制 static propTypes = { name: PropTypes.string.isRequired, // 限制类型为字符串,且为必传数据 sex: PropTypes.string, // 限定类型为字符串 age: PropTypes.number, // 限定类型为数值 speak: PropTypes.func // 限定类型为函数 } // 指定默认标签属性值 static defaultProps = { sex: '男', age: 18 }
注意:写这两个属性之前必须引入prop-types.js这个依赖包。
(3)关于 constructor 构造器的一些说明。
构造器是否接收 props,是否传递给 super,取决于:是否希望在构造器中通过 this 访问 props。如果非必要,构造器函数完全可以不写。
以下给出的是官方文档的内容以及2.1.2所用到的 constructor 代码:
constructor(props) { super(props) // 通过给 this.state 赋值对象来初始化内部 state this.state = { isHot: false }; // 为事件处理函数绑定实例 this.changeWeather = this.changeWeather.bind(this); }
组件内的标签可以定义 ref 属性来标识自己。
2.3.1 字符串形式的 ref(官方不建议使用)
案例效果:点击按钮显示输入的内容。(2.2.2与2.2.3都是这个案例)
2.3.2 回调形式 ref
【官方文档】关于回调形式 ref 存在问题的说明:
2.3.3 createRef 创建 ref 容器
语法:
(1)创建一个容器:myRef = React.createRef()
(2)将结点存储到容器:ref={this.myRef} type="text" placeholder='...' />
(3)获取容器的相关内容:this.myRef.current.value
2.3.4 总结
字符串形式 ref | ref="input1"/> |
回调形式 ref | ref={(c)=>{this.input1 = c}} |
createRef 创建 ref 容器 | myRef = React.createRef() ref={this.myRef}/> |
(1)通过onXxx属性指定事件处理函数。【 onclick => onClick 】
① React 使用的是自定义(合成)事件,而不是使用的原生DOM事件。【为了更好的兼容性】
② React 中的事件是通过事件委托方式处理的(委托给组件最外层的元素)。【为了更高效】
(2)通过 event.target 得到发生事件的 DOM 元素对象。【为了不要过度的使用 ref 】