React JSX
JSX是什么
- JSX是一种JavaScript的语法扩展(eXtension),全称为JavaScript XML
JSX的书写规范
- JSX的顶层只能有一个根元素,所以我们可以在外层包裹一个div元素(或使用Fragment)
- 为了方便阅读,我们通常在jsx的外层包裹一个小括号(),这样可以方便阅读,并且jsx可以进行换行书写
- JSX中的标签可以是单标签,也可以是双标签(注意:如果是单标签,必须以/>结尾)
JSX嵌入变量作为子元素
- 当变量是Number、String、Array类型时,可以直接显示,这里注意React会自动展开数组
- 当变量是null、undefined、Boolean类型时,内容为空
- 希望可以显示null、undefined、Boolean,那么需要转成字符串转换的方式有很多,比如toString方法、和空字符串拼接,String(变量)等方式
- Object对象类型不能作为子元素(not valid as a React child)
JSX嵌入表达式
- 运算表达式
- 三元运算符
- 执行一个函数
JSX属性绑定
这里要注意CSS中class和内联样式的写法
- class需要写成className,因为class是一个关键字已被占用
- 内联样式需要写成
style={{color:'blue'}}
这种格式,属性按对象格式填写
JSX事件绑定
- React事件绑定采用小驼峰(camelCase),例如
onClick = {}
- 我们需要通过{}传入一个事件处理函数,这个函数会在事件发生时被执行
事件绑定中的this问题
假设我们使用handle(){}
在class组件中定义回调函数,在元素上使用onClick={this.handle}
的方式绑定回调函数,那么之后在handle函数体中使用this就会发现它是一个undefined,出现这个问题的原因就在于回调函数的调用并非是组件实例进行的,因此有以下三种解决办法:
- 使用bind绑定this:在constructor中加上
this.handle = this.handle.bind(this)
- 使用ES6的class fields语法:
handle = (){}
- 事件监听时传入箭头函数
onClick={() =>this.handle()}
事件绑定中的参数传递
- 获取Event对象:默认即传入,直接接受即可
- 获取其他参数:可以使用一个箭头函数,利用箭头函数传入其他相关参数,如
onClick={() => this.handleClick(index)}
条件渲染
- 在Vue中,我们通过指令来控制:v-if,v-show等
- 在React中,所以条件判断都与普通的JavaScript一致
常见方式如下:
- 条件判断语句
- 三元运算符
- 与运算符&&
- 控制display是否为none(即实现v-show的效果)
列表渲染
主要是使用数组方法如map(),slice(),filter()等
JSX的本质
实际上,jsx仅仅是React.createElement(component, props,…children)函数的语法糖,也就是说,所有的jsx最后都会被转换成React.createElement的函数调用,他的作用就是用来简化创建虚拟DOM
createElement源码地址:react/ReactElement.js,create Element需要传递三个参数
type
- 当前ReactElement的类型
- 如果是标签元素,那么就用字符串表示’div’
- 如果是组件元素,那么就直接使用组件的名称
- config
- 所有的jsx中的属性都在config中以对象的属性和值的形式存储
- 比如传入className作为元素的class
children
- 存放在标签中的内容,以children数组的方式进行存储
那么我们通过React.createElement创建出了一个ReactElement对象,它的作用又是什么呢?
React利用ReactElement对象组成了一个JavaScript对象树
而JavaScript对象树就是虚拟DOM(Virtual DOM)
那为什么React要使用虚拟DOM呢?
虚拟DOM使用Diff算法,避免渲染重复元素,优化渲染速度,最小化页面重绘
跨平台渲染
而按React官方的说法:virtual DOM是一种编程理念,虚拟DOM帮助我们从命令式编程转到了申明式编程的模式
在这个理念中,UI以以一种理想化或者说虚拟化的方式保存在内存中,并且它是一个相对简单的JavaScript对象
我们可以通过ReactDOM.render上虚拟DOM和真实DOM同步起来,这个过程叫做协调 (Reconciliation)
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!