您的位置:首页 > Web前端 > React

React入门笔记(一) — 深入理解JSX

2017-06-19 16:13 621 查看


《一》、理解JSX
  
JSX
Javascrpt
XML
— — 一种在
React
组件内部构建标签的类
XML
语法。 

  
JSX
并不是新语言,也没有改变
JavaScript
的语法,只是一种基于
ECMAScript
的新特性,一种定义带属性树结构(
DOM
结构)的语法 

  
react
 可以不使用 
JSX
 来编写组件,但是使用 
JSX
 可以让代码可读性更高、语义更清晰、对 
React
 元素进行抽象等等。


一、使用JSX好处

  1、允许使用熟悉的语法来定义HTML元素树  2、提供了更加语义化且易懂的标签 

  3、程序结构更容易被直观化  4、抽象了
React Element
的创建过程 

  5、可以随时掌控HTML标签以及生成这些标签的代码  63、是原生
javascript


使用JSX和不使用JSX的代码对比如下:
//开闭标签,在构建复杂的树形结构时,比函数调用和对象字面量更易读
//#使用JSX
<div className="red">Children Text</div>;
<MyCounter count={3 + 5} />;
// 此处给一个js对象设置"scores"属性
var gameScores = {
player1: 2,
player2: 5
};
<DashboardUnit data-index="2">
<h1>Scores</h1>
<Scoreboard className="results" scores={gameScores} />
</DashboardUnit>;

//#不使用JSX
React.createElement("div", { className: "red" }, "Children Text");
React.createElement(MyCounter, { count: 3 + 5 });

React.createElement(
DashboardUnit,
{ "data-index": "2" },
React.createElement("h1", null, "Scores"),
React.createElement(Scoreboard, { className: "results", scores: gameScores })
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24


二、JSX 语法

【注意】 
JSX
代码需经babel 编译成javscript,目前主流浏览器才能正常识别,即在head中需添加:
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
1
1

React还需依赖的另外2个文件:react.js 是 React 的核心库,react-dom.js 是提供与 DOM 相关的功能, 

并将
JSX
代码放在
<script type='text/babel'>
 … 
</script>
中编写
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="build/react.js"></script>
<script src="build/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

【推广】上面必需核心库找不到的话,可以上本人github下载:https://github.com/mqy1023/react-basejs

  
JSX
HTML
JavaScript
混写的语法,当遇到<
JSX
就当
HTML
解析,遇到 { 就当
JavaScript
解析。
var names = ['Alice', 'Emily', 'Kate'];
ReactDOM.render(
<div>
{
names.map(function (name) {
return <div>Hello, {name}!</div>
})
}
</div>,
document.getElementById('example')
);
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11


 
理解Array.prototype.map,返回一个新的数组
var friends = ['Jake Lingwall', 'Murphy Randall', 'Merrick Christensen'];
var listItems = friends.map(function(friend){
return "<li> " + friend + "</li>";
});
console.log(listItems); // ["<li> Jake Lingwall</li>", "<li> Murphy Randall</li>", "<li> Merrick Christensen</li>"];
1
2
3
4
5
1
2
3
4
5

  
JSX
 允许直接在模板插入 
JavaScript
 变量。如果这个变量是一个数组,则会展开这个数组的所有成员
// arr变量是一个数组,结果 JSX 会把它的所有成员,添加到模板
var arr = [
<h1>Hello world!</h1>,
<h2>React is awesome</h2>,
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById('example')
);
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9



  在React中,一个组件的HTML标签与生成这些标签的代码内在地紧密联系在一起。这意味和我们可以轻松地利用
Javascript
强大魔力 

  1、使用三目运算符
render: function() {
return <div className={this.state.isComplete ? 'is-complete' : ''}>...</div>;
}
1
2
3
1
2
3

  2、使用变量/函数
getIsComplete: function() {
return this.state.isComplete ? 'is-complete' : '';
},
render: function() {
var isComplete = this.getIsComplete();
return <div className={isComplete}>...</div>;

//或者直接返回函数
return <div className={this.getIsComplete()}>...</div>;
}
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10

  3、使用逻辑与(&&)或者逻辑或( || )运算符 

    由于对于null或false值React不会输出任何内容,因此可以使用一个后面跟随了期望字符串的布尔值来实现条件判断。如果这个布尔值为true,后续字符串会被使用
render: function() {
return <div className={this.state.isComplete && 'is-complete'}>...</div>;
}
1
2
3
1
2
3

    逻辑或,this.props.name为空时,className值等于is-complete
render: function() {
return <div className={this.props.name || 'is-complete'}>...</div>;
}
1
2
3
1
2
3

  4、函数调用
var HelloWorld = React.createClass({
render: function () {
return <p>Hello, {(function (obj) {
return obj.props.name ? obj.props.name : "World";
})(this)}</p>
}
});
1
2
3
4
5
6
7
1
2
3
4
5
6
7


三、创建并渲染组件

//1、React.createClass 是用来创建一个组件
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
});
//2、ReactDOM.render渲染组件
ReactDOM.render(
<HelloMessage name="John" />,
document.getElementById('example')
);
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11



《二》、JSX和HTML不同点


一、渲染HTML标签和React组件

  
React.render
方法可以渲染
HTML
结构,也可以渲染
React
组件。 

    1、渲染
HTML
标签,声明变量采用首字母小写
var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.body);
1
2
1
2

    2、渲染
React
组件,声明变量采用首字母大写
var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
ReactDOM.render(myElement, document.body);
1
2
3
1
2
3


二、非DOM属性

1、键(
key
) 

  
key
是一个可选的唯一标识符,当两个已经在于
DOM
中的组件交换位置时,
React
能够匹配对应的
key
并进行相应的移动,且不需要完全重新渲染
DOM
,提供渲染性能 


 

2、引用(
ref
) 

  
ref
允许父组件在
render
方法之外保持对子组件的一个引用。在
JSX
中,你可以通过属性中设置期望的引用名来定义一个引用。
render: function() {
return <div>
<input ref="myInput" ...> </input>
</div>
);
}
1
2
3
4
5
6
1
2
3
4
5
6

  然后你可以在组件的任何地方使用
this.refs.myInput
获取这个引用了。通过引用获取到的这个对象被称为支持实例。它并不是真的
DOM
,而是React在需要时用来创建
DOM
的一个描述对象。你可以使用
this.refs.myInput.getDOMNode()
访问真实的
DOM
节点。

3、设置原始的
HTML
 

  比如我们有一些内容是用户输入的富文本,希望展示相应的样式
var content='<strong>content</strong>';
ReactDOM.render(
<div>{content}</div>,
document.body
);
1
2
3
4
5
1
2
3
4
5

结果页面直接输出内容了: 


 
React
默认会进行
HTML
的转义,避免
XSS
攻击,如果要不转义,可以这么写:
ReactDOM.render(
<div dangerouslySetInnerHTML={{__html: "<strong>content</strong>"}}></div>,
document.body
);
1
2
3
4
1
2
3
4


三、事件

  在所有的浏览器中,事件名已经被规范化并统一用onXXX驼峰形式表示
var BannerAd = React.createClass({
handleClick: function(event) {
//...
},
render: function() {
return <div onClick={this.handleClick}>Click Me!</div>;
}
})
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8

【注意】 React自动绑定了组件所有方法的作用域,因此你不需要手动绑定
handleClick: function(event) {...},
render: function() {
//反模式 ————在React中手动给组件实例绑定
//函数作用域是没有必要的
return <div onClick={this.handleClick.bind(this)}>...</div>;
}
1
2
3
4
5
6
1
2
3
4
5
6


四、特殊属性

  由于JSX会转换为原生的Javascript函数,因此有一些关键词我们是不能用的——如
class
for
,对应JSX中属性写成
className
htmlFor

//#使用JSX
ReactDOM.render(
<label className="xxx" htmlFor="input">content</label>,
document.getElementById('example')
);
//#不使用JSX
ReactDOM.render(
React.createElement('label', {className: 'xxx', htmlFor: 'input'}, 'content'),
document.getElementById('example')
);
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10


五、style样式

  
React
把所有的内联样式都规范化为驼峰形式,与
Javascript
DOM
sytle
属性一致。第一重大括号表示这是
JavaScript 语法,第二重大括号表示样式对象。
React.render(
<div style={{color:'red'}}>
xxxxx
</div>,
document.body
);
////////////////////////////
var style = {
color:'red',
borderColor: '#999'
}
ReactDOM.render(<div style={style}>xxxxx</div>, document.body);
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12


六、注释

JSX
本质就是
Javascript
,因此你可以在标签内添加原生的
javascript
注释。
注释两种形式 
当作一个元素的子节点
内联在元素的属性中

var content = (
<Nav>
{/* 一般注释, 用 {} 包围 */}
<Person
/* 多
行
注释 */
name={window.isLoggedIn ? window.name : ''} // 行尾注释
/>
</Nav>
);
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11



《三》、JSX延伸属性


一、不要改变props

  如果提前就知道了组件的属性的话,写起来很容易。例如
component
组件有两个动态的属性foo和bar:
var component = <Component foo={x} bar={y} />;
1
1

  而实际上,有些属性可能是后续添加的,我们没办法一开始就确定,我们可能会写出下面不好的代码:
var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y; // also bad
1
2
3
1
2
3

  这样写是错误的,因为我们手动直接添加的属性
React
后续没办法检查到属性类型错误,也就是说,当我们手动添加的属性发生类型错误时,在控制台是看不到错误信息的。

  在
React
的设定中,初始化完
props
后,
props
是不可变的。改变
props
会引起无法想象的后果。


二、延伸属性

  为了解决这个问题,
React
引入了属性延伸
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
1
2
3
4
1
2
3
4

  当需要拓展我们的属性的时候,定义个一个属性对象,并通过
{...props}
的方式引入,
React
会帮我们拷贝到组件的
props
属性中。重要的是—这个过程是由
React
操控的,不是手动添赋值的属性。

  需要覆盖的时候可以这样写:
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
1
2
3
1
2
3



《四》、JSX 陷阱


一、自定义HTML属性

  如果往原生 
HTML
 元素里传入 
HTML
 规范里不存在的属性,
React
 不会显示它们。
ReactDOM.render(
<div dd='xxx'>content</div>,
document.body
);
1
2
3
4
1
2
3
4



如果需要使用自定义属性,要加 data- 前缀。
ReactDOM.render(
<div data-dd='xxx' aria-dd='xxx'>content</div>,
document.body
);
1
2
3
4
1
2
3
4



二、组件render渲染函数中return注意点 

如果return和JSX语句开头在同一行时,不需要括号;否则要括号包裹
//正确写法1
var HelloMessage = React.createClass({
render: function() {
return <h1>
Hello {this.props.name}</h1>;
}
});
//正确写法2
render: function() {
return <h1>Hello {this.props.name}</h1>;
}
//正确写法3
render: function() {
return (
<h1>Hello {this.props.name}</h1>);
}

//错误写法
render: function() {
return
<h1>Hello {this.props.name}</h1>;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: