一、类组件 (class组件)
- 特点:用ES6面向对象语法,有生命周期、有this、有state、有上下文、有ref、永远不能使用Hooks
- 缺点:相对函数式组件来讲,性能较差
- 开发:相对函数式组件写法,显得很麻烦
二、理解jsx语法
- jsx = JavaScript XML,是一种语法,由Fackbook发布的,浏览器是不支持这种语法
- 在编写React组件视图结构时,JSX是可选的(你可以使用React.createElement('tag',{},[])编写视图结构)
- JSX语法最终会被 @babel/preset-react 进行编译,编译的结果就是React.createElement()这种语法
- 要求:随时有能力把JSX语法转换成React.createElement()语法,反之亦然
- JSX元素:本质上就是React.createElement()的结果,是变量,也是对象,并且是不可变对象
- 为什么JSX元素要设计成不可变对象?因为JSX元素最终会渲染成真实DOM,所以不能直接操作“原材料”,只能使用声明式
- 什么是元素?什么是组件?
- 由class或者function定义的东西叫组件,由JSX语法或React.createElement()返回的结果叫做元素。你可以把元素理解成是组件实例化的对象
三、盘点JSX语法细节
- 在JSX中可以嵌套表达式,使用 {} 来嵌套,在JSX视图,凡是动态的变量(表达式)都使用{}包起来
- 定义视图比较复杂时,建议换行。像HTML那样对齐,换行后建议用()把JSX元素整体包裹起来
- JSX是变量,也是表达式,所以JSX元素可以作为函数的入参,也可以作为函数的返回值,还可以用在if/for循环中
- JSX语法有三个变化属性:className(class)、tabIndex(tabindex)、htmlFor(for)
- JSX语法有三种新增的属性:key(用于列表渲染),ref(快捷的DOM方式)
- JSX中,不仅自定义组件可以使用单闭合,任何html标签都可以单闭合,比如、
- 动态 style 语法:<div style={{ csskey:'cssValue' }}>
- className语法:<div className='box' className={
${cc} ff}> - 在JSX中,使用 {} 渲染后端接口数据,默认支持防注入攻击(XSS)
- JSX是对象,因为JSX变量是React.createElement()的返回值,这个返回值是对象结构,所以JSX是对象,这种JSX对象就是"Fiber单元"很多很多嵌套的"Fiber单元"就构成了"Fiber树"(双向列表)
- JSX语法中,所有的React组件(由class或者function定义)的名称都必须以大写字母开头,比如:
<A />、<MyButton /> - JSX支持“.”点语法,比如React.Componenet, <React.Fragment />、<Qf.Button />
- 对自定义组件来讲,props是自定义属性;对HTML元素来讲,props就是你们学过的那些HTML标签属性,在使用props时,不能把js语句赋值给props,props只能接收表达式
- 在JSX中,向子组件传递props时,支持属性展开语法,像这样<Child {...chProps} />
- 当我们在使用自定义组件时,哪些被自定义所嵌套的内容,在子组件中使用props.children来接收他们。详解一下props.children,可以是任何数据类型的数据,比如基本数据类型、引用数据类型、也可以是函数
- 在JSX语法中,默认就是支持对数组的直接渲染,像这样 { [,true,null,100,{a:1,b:2},[1,2,3]] }
- 在JSX中,使用{}渲染Boolean、null、undefined,都会被忽略,也就是说不生成文本节点
- 在React中,封装组件时,无论是render的返回值,还是函数式组件的返回值,还可以是组件,像这样 const Foo=(props)=>([])
四、学习 state 声明式
-
如何定义state?
- 在类组件中,在constructor()中使用this.state={} 来定义:
- 在函数式中,自React16.8以后可以使用 useState()来定义
-
如何使用state?
- 在类组件中,通过this.state来访问声明式变量;
- 在函数式组件中,直接访问useState的结果
-
如何正确的修改state声明式变量?
- 在类组件中,使用专属方法this.setState()来修改;
- 在函数式组件中,使用useState()返回值的第二个参数来修改。
-
详解 this.setState()的两种写法
- this.setState({ },callback) 当我们修改state时,如果新值与旧值无关,建议使用这种写法
- this.setState((state,props)=>{ },callback) 当我们修改state时,如果新值与旧值有关,建议使用这种写法
-
详解 this.setState()的异步性
- 在React(V17/V16)中,this.setState()在合成事件(on*系列事件、生命周期)中,是异步的;在宏任务、Promise.then()中是同步的
- 在React(V18)中,无论this.setState()在哪里。都是异步的。这种特性,被称之为“并发模式”
- 为什么是要把this.setState()这个语句定义成异步的呢?为了性能优化
-
详解 this.setState()的自动合并
- 什么是this.setState()的自动合并呢?在同一个函数域中,多个this.setState()会自动合并,以减少没有必要的Diff运算(协调运算)
- 自动合并的规则:是一种浅合并
-
事件绑定
- 在类组件中,使用
<div onEventName={this.handler.bind(this,10)} />, - 还可以使用
<div onEventName={()=>this.handler(10)} /> - 在函数式组件中,只能使用箭头函数的方式绑定
- 在类组件中,使用