jsx基础

1 初识jsx

React 使用 JSX 来替代常规的 JavaScript。

JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。

我们不需要一定使用 JSX,但它有以下优点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
  • 它是类型安全的,在编译过程中就能发现错误。
  • 使用 JSX 编写模板更加简单快速。

    JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。上面代码的运行结果如下。

JSX语法,像是在Javascript代码里直接写XML的语法,实质上这只是一个语法糖,每一个XML标签都会被JSX转换工具转换成纯Javascript代码,React 官方推荐使用JSX, 当然你想直接使用纯Javascript代码写也是可以的,只是使用JSX,组件的结构和组件之间的关系看上去更加清晰。

JSX是一种语法糖,关于如何编译JSX代码可以参见如下链接

bable%20%7B%0A%20%20return%20%3Cdiv%3EHello%20world!%3C%2Fdiv%3E%3B%0A%7D)

1
var person = <Person name={window.isLoggedIn ? window.name : ''} />;

上述代码经过JSX编译后会得到:

1
2
3
4
var person = React.createElement(
Person,
{name: window.isLoggedIn ? window.name : ''}
);
1
2
3
<MyButton color="blue" shadowSize={2}>
Click Me
</MyButton>
1
2
3
4
5
React.createElement(
MyButton,
{color: 'blue', shadowSize: 2},
'Click Me'
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//使用JSX
React.render(
<div>
<div>
<div>content</div>
</div>
</div>,
document.getElementById('example')
);
//不使用JSX
React.render(
React.createElement('div', null,
React.createElement('div', null,
React.createElement('div', null, 'content')
)
),
document.getElementById('example')
);
  • r如果标签是以小写字母开头,那么React会寻找内置标签,比如div sapn等
  • 如果标签是以大写字母开头,React会调用React.createElement去编译这个标签

2 我们可以在JSX中

  • 插入任何js表达式
1
2
3
4
5
6
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
1
2
3
4
5
6
7
8
<div id="root"></div>
<script type='text/babel'>
ReactDOM.render(
<div >{1+3}</div>
,
document.getElementById('root')
)
</script>
  • props如果没有提供值,那么默认值是true,以下声明是等价的
1
2
3
<MyTextBox autocomplete />
<MyTextBox autocomplete={true} />
  • props声明可以是字符串类型以及js表达式 {} 包括的代码
1
2
3
<MyComponent message="hello world" />
<MyComponent message={'hello world'} />
  • 指明类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const element1 = <div className='hello'>hello1</div>
//等价于以下
const element2 = React.createElement(
'div',
{className:'sayHello2'},
'hello2'
)
//内部大概的解析过程
// Note: this structure is simplified
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world'
}
};

完整代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<div id="root1"></div>
<div id="root2"></div>
<script type='text/babel'>
const user = {
firstName:'Jhon',
lastName:'Kobe'
};
function formatName(user){
if(user){
return user.firstName + " " + user.lastName ;
}
return 'stranger hello '
}
const element1 = <div className='hello'>hello1</div>
const element2 = React.createElement(
'div',
{className:'sayHello2'},
'hello2'
)
ReactDOM.render(
element1,
document.getElementById('root1')
)
ReactDOM.render(
element2,
document.getElementById('root2')
)
</script>
  • 注意render函数中只能有一个顶层标签
1
2
3
4
5
6
7
8
9
10
<div id="root"></div>
<script type='text/babel'>
ReactDOM.render(
<div data-attr = 'name'>this is a test
<h2>this is a test 2 </h2>
</div>,
document.getElementById('root')
)
</script>

以下是错误写法,顶层标签只能含有一个。

1
2
3
4
5
6
7
8
<div id="root"></div>
<script type='text/babel'>
ReactDOM.render(
<div data-attr = 'name'>this is a test</div>
<h2>this is a test 2 </h2>,
document.getElementById('root')
)
</script>
1
2
3
4
5
6
7
8
9
10
11
<script type='text/babel'>
var HelloWorld = React.createClass({
render : function(){
return <h1>hello {this.props.name1}</h1>
<h1>hello {this.props.name2}</h1>
}
})
<HelloWorld name1 = 'Jhon' name2 = "JiM"/>
//这样也无法渲染出来
</script>
  • 可以使用三元运算符,但是不能使用if-else表达式
1
2
3
4
5
6
7
8
9
10
const i = 1 ;
ReactDOM.render(
<div >{
i == 1 ? ' 2' : '3'
}
</div>
,
document.getElementById('root')
)