JSX简介
示例
// 这里是JSX语法,所以可以吧html代码片段赋值给一个变量
// 可以认为这个html片段就是一个值,
// 其最后会被转换为VDOM,最后在页面上渲染为真实的DOM
const res = <h2>Hello World</h2>
ReactDOM.render(res, document.getElementById('app'))
1.1 JSX的2个先决条件
- 使用了
babel进行编译和转换 - 在
script上声明了使用babel进行编译 即type='text/babel'
1.2 什么是JSX
- JSX是一种JavaScript的语法扩展(eXtension),也在很多地方称之为JavaScript XML,因为看起就是一段XML语法;
- 它用于描述我们的UI界面,并且其完成可以和JavaScript融合在一起使用;
- 它不同于Vue中的模块语法,你不需要专门学习模块语法中的一些指令(比如v-for、v-if、v-else、v-bind);
1.3 为什么使用JSX
React的设计哲学和别的框架的设计思想是不一样的,例如在Vue中就使用了template,script,style将界面,样式,布局进行了分离
但是在React中的设计哲学是all in js,在React中,认为所有的内容都可以写在JS中,界面和布局与js代码存在内在耦合,其主要表现为
- 比如UI需要绑定事件(button、a原生等等);
- 比如UI中需要展示数据状态,在某些状态发生改变时,又需要改变UI
所以React没有讲标记分离到不同的文件中,而是将它们组合到了一起,这个地方就是组件 (Component)
在这里,我们只需要知道,JSX其实是嵌入到JavaScript中的一种结构语法;
1.4 JSX的一些书写规范
-
JSX的顶层只能有一个根元素,所以我们很多时候会在外层包裹一个原生div或main标签(或者使用后面我们学习的Fragment) -
为了方便阅读,我们通常在
jsx的外层包裹一个小括号(),这样可以方便阅读,并且jsx可以进行换行书写;- 这个括号不是必须的,但是加上括号和不加括号是有些许的区别的
- 加上括号后,书写JSX是可以进行换行书写的,如果没有括号,所有的jsx必须书写在一行,如果换行会报错
- 加上括号后,相比不加括号,更利于代码的阅读和维护
- 这个括号不是必须的,但是加上括号和不加括号是有些许的区别的
-
在jsx中可以书写单标签,也可以书写双标签,但是如果使用了单标签的时候,JSX中使用的是严格语法,也就是说在JSX中
单标签必须闭合,例如
<App />
1.5 JSX的注释
JS中的注释
// 行内注释
// ...
// 块级注释
/*
....
*/
// 多行注释
/**
*
*
*/
JSX中的注释
{/* 我是jsx中的注释 */}
{/*
如果在JSX中使用// 或者直接使用/**/来进行注释的话
这些注释会被作为文本节点被输出出来
*/}

在JSX中使用JS注释,其会被作为文本节点,然后输出
1.6 在JSX中使用变量
情况1:
Number,String,Array可以被正常渲染class App extends React.Component{ constructor(str, num, arr) { super() this.state = { str: 'Klaus', num: 23, arr: ['Klaus', 'Alice', 'Kobe'] } } render() { {/* 解构赋值 */} const {str, num, arr} = this.state return ( <div> <div>{ str }</div> <div>{ num }</div> {/* JSX在读取数组数据的时候 会自动取出其中的每一个数组元素后显示 */} <div>{ arr }</div> </div> ) } } ReactDOM.render(<App />, document.getElementById('app'))
情况2:
null,undefined, boolean默认是不会被React渲染在页面上class App extends React.Component{ constructor() { super() this.state = { nullElem: null, undefinedElem: undefined, trueElem: true, falseElem: false } } render() { const {nullElem, undefinedElem, trueElem, falseElem} = this.state return ( <div> <div>{ nullElem }</div> <div>{ undefinedElem }</div> <div>{ trueElem }</div> <div>{ falseElem }</div> </div> ) } } ReactDOM.render(<App />, document.getElementById('app'))结果: 界面上没有任何的输出
React中不显示输出null,undefined,boolean值的原因render() { return ( <div> {/* 这是传统的写法 */} <div>{ this.state.age > 18 ? 'OK' : '' }</div> {/* 在React中可以这么写 */} <div>{ this.state.age > 18 ? 'OK' : null }</div> <div>{ this.state.age > 18 ? 'OK' : undefined }</div> {/* flag 是在state中定义的boolean值 如果flag为true 输出结果为 this.state.name 如果flag为false 输出结果为 false */} <div>{ this.state.flag && this.state.name }</div> </div> ) }如果希望将
null,boolean,undefined可以显示在页面上只有将这些转化为字符串后才可以正常显示
转换方式如下:
- 调用
toString方法,只适合于Boolean.null, undefined是没有toString方法的- 调用
String方法,null,undefined,boolean都是可以被调用的- 直接加上空字符串,例如
null + '',null,undefined,boolean都是可以被调用的
情况3:对象类型不能作为子元素(not valid as a React child)
class App extends React.Component{ constructor() { super() this.state = { obj: { name: 'Klaus', age: 23 } } } render() { return ( <div> <div>{ this.state.obj }</div> </div> ) } } ReactDOM.render(<App />, document.getElementById('app'))结果:
JSX最后会被做为React的子类来进行解析,但是对象是不可以作为React的子类的,因此报错
1.7 在JSX中使用表达式
this.state = {
firstName: 'Klaus',
lastName: 'Wang',
isLogin: true
}
render() {
const {firstName, lastName, isLogin} = this.state
return (
<div>
{/* JSX中可以使用运算符表达式 */}
<div>{ firstName + ' ' + lastName }</div>
<div>{ 10 + 4 }</div>
{/* JSX中可以使用三目表达式(三元运算符) */}
<div>{ isLogin ? '欢迎回来' : '请先登录' }</div>
{/* 其余的运算符包括逻辑与,逻辑或,map,filter等 */}
</div>
)
}
this.state = {
firstName: 'Klaus',
lastName: 'Wang'
}
getFullName() {
// 注意: 这里的this是正确的, 默认不是undefined
return this.state.firstName + this.state.lastName
}
render() {
return (
<div>
{/*
这个方法是我们自己定义的方法 ,是我们自己调用的
和之前的事件callback 不一样,事件callback是React来替我们进行调用的
但是这里是我们自己主动进行调用,所以这里我们隐式绑定的this就是实例对象
所以不需要在认为进行绑定
*/}
{ this.getFullName() }
</div>
)
}

