简介:从根本上来说,JSX语法提供了一种创建React元素的语法糖,JSX语句可以编译成:
React.createElement(component, props, …children)的形式,比如:
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' )
|
指定React元素的类型
JSX标签的头部,决定了React元素的类型,大写的标签,意味着JSX的标签与React的组件一一对应,比如
(1)必须包裹在一定的范围内
1 2 3 4 5 6 7
| import React from 'react'; import CustomButton from './CustomButton'; function WarningButton() { return <CustomButton color="red" />; }
|
比如这样,引入了2个组件,构成了一个新的组件WarningButton,组件的返回值的元素,必须包含在一定范围内,这里通过函数的’{ ‘, ’ } ‘实现包裹的效果。
(2)用户定义的组件必须大写
我们前面已经说过,JSX的标签与组件是一一对应的,当我们使用JSX语法,引用组件的时候,标签必须要大写(同时定义组件的函数名也必须是大写的)。
1 2 3 4 5 6 7
| function Hello(){ return <h2>Hello,World</h2> } <Hello/>
|
(3)不能在运行期间,动态的选择类型
我们不能在JSX中,动态的规定组件的类型,举例来说:
1 2 3 4 5 6 7 8 9 10 11 12
| import React from 'react'; import { PhotoStory, VideoStory } from './stories'; const components = { photo: PhotoStory, video: VideoStory }; function Story(props) { return <components[props.storyType] story={props.story} />; //这样写是不对的,我们在返回的组件中,动态定义了组件,这种动态的定义是无效的 }
|
应该改写为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import React from 'react'; import { PhotoStory, VideoStory } from './stories'; const components = { photo: PhotoStory, video: VideoStory }; function Story(props) { const SpecificStory = components[props.storyType]; return < SpecificStory story={props.story} />; //这样就是正确的,我们不要在JSX的标签中使用动态定义 }
|
JSX中的Props属性
(1)JS表达式
可以通过{},包裹js的语法来使用。比如:
1
| <MyComponent foo={1 + 2 + 3 + 4} />
|
等价于:
1
| <MyComponent foo={10} />
|
如果不是js表达式,则不能包裹在{}中使用。
(2)Props属性的默认值
Props上的属性可以有默认值,并且默认值为true,比如:
1 2
| <MyTextBox autocomplete /> <MyTextBox autocomplete={true} />
|
上面这两个式子是等价的,但是不推荐使用默认值,因为在ES6
的语法中{foo}
代表的意思是:{foo:foo}
的意思,并不是{foo:true}
。
(3)扩展属性
可以通过ES6的…方法,给组件赋属性值,例如:
1 2 3 4 5 6 7 8
| function App1() { return <Greeting firstName="Ben" lastName="Hector" />; } function App2() { const props = {firstName: 'Ben', lastName: 'Hector'}; return <Greeting {...props} />; }
|
上面的这两种方式是等价的。
JSX中的children
(1)children中的function
我们来考虑自定义组件中包含函数的情况:
1 2 3 4 5 6 7
| function ListOfTenThings() { return ( <Repeat numTimes={10}> {(index) => <div key={index}>This is item {index} in the list</div>} </Repeat> ); }
|
那么何时调用这个children中的方法呢?
1 2 3 4 5 6 7
| function Repeat(props) { let items = []; for (let i = 0; i < props.numTimes; i++) { items.push(props.children(i)); } return <div>{items}</div>; }
|
我们从上述的Repeat组件的定义中可以看出来,children中的方法按此定义会一直执行10次。
(2)忽略Boolean,Null以及Undefined
false
,null
,undefined
以及true
是不能通过render()方法,呈现在页面上的,下面的这些div块的样式
相同,都是空白块:
1 2 3 4 5
| <div /> <div></div> <div>{false}</div> <div>{null}</div> <div>{true}</div>
|
这种属性,在通过render呈现元素的时候,是十分有用的,比如我们只想在div元素中展现Head组件,
例子如下:
1 2 3 4
| <div> {showHeader && <Header />} <Content /> </div>
|
这里的逻辑是,只有showHeader==true
,在会在页面呈现Header
组件,否则为null
,即为不显示任何东西,这相当于一个if
的判断了。
再举一个例子:
1 2 3 4 5
| <div> {props.messages.length && <MessageList messages={props.messages} /> } </div>
|
在这个div
中,我们需要知道的是即使元素为0,0是能够呈现在页面中的。也就是说上述代码中,只要
props.messages
数组存在,不管长度是否为0
都是存在的。(这里不同于js
,js
中的语法认为0==false
)
(3)如何显示Null,Undefined和Boolean
如果我们一定要再页面上显示Null
等,可以将其先转化为字符串之后再显示。
1 2 3
| <div> My JavaScript variable is {String(myVariable)}. </div>
|
通过String的转化后就能在页面上显示了。
参考地址
http://blog.csdn.net/liwusen/article/details/53383922