深入jsx
本质上来讲,JSX 只是为 React.createElement(component, props, …children)提供的语法糖。
即:babel编译器可以将jsx转换成js。
<div className="sidebar" />
编译为:
React.createElement(
'div',
{className: 'sidebar'},
null
)
React必须声明
1.React组件将会被编译为同名变量并被引用,所以必须先声明。如组件必须先声明再引用。
2.由于 JSX 编译后会调用 React.createElement 方法,所以在你的 JSX 代码中必须首先声明 React 变量。
import React from 'react';
import CustomButton from './CustomButton';
function WarningButton() {
// 返回 React.createElement(CustomButton, {color: 'red'}, null);
return <CustomButton color="red" />;
}
备注:如果你使用
点表示法
作用:方便从一个模块中导出许多React组件。
import React from 'react';
const MyComponents = {
DatePicker: function DatePicker(props) {
return <div>Imagine a {props.color} datepicker here.</div>;
}
}
function BlueDatePicker() {
return <MyComponents.DatePicker color="blue" />;
}
首字母大写
当元素类型以小写字母开头时,它表示一个内置的组件,如
以大写字母开头的类型,如 编译为 React.createElement(Foo),并它正对应于你在 JavaScript 文件中定义或导入的组件。(小写开头会被认为是html原生标签)
即:以大写开头命名组件,或者在jsx使用之前将其赋值给大写开头的变量。
import React from 'react';
// 正确!组件名应该首字母大写:
function Hello(props) {
// 正确!div 是有效的 HTML 标签:
return <div>Hello {props.toWhat}</div>;
}
function HelloWorld() {
// 正确!React 能够将大写开头的标签名认为是 React 组件。
return <Hello toWhat="World" />;
}
通过表达式来确定raect元素类型
不能通过表达式来确定react标签名,可以将它赋值给大写开头的变量。
import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
photo: PhotoStory,
video: VideoStory
};
function Story(props) {
// 正确!JSX 标签名可以为大写开头的变量。
const SpecificStory = components[props.storyType];
return <SpecificStory story={props.story} />;
}
js表达式
使用 JavaScript 表达式
你可以传递任何 {} 包裹的 JavaScript 表达式作为一个属性值。
if 语句和 for 循环在 JavaScript 中不是表达式,因此它们不能直接在 JSX 中使用,但是你可以将它们放在周围的代码中。
字符串常量
字符串常量也可以作为属性传递,但是值会被解析成htnl非转义字符串。
<MyComponent message="<3" />
<MyComponent message={'<3'} />
如果没有给属性传值,则他默认为true。
<MyTextBox autocomplete />
<MyTextBox autocomplete={true} />
不建议,因与ES6对象简洁写法冲突。
使用扩展属性
使用扩展属性可以传递整个属性对象。
function App1() {
return <Greeting firstName="Ben" lastName="Hector" />;
}
等价于:
function App2() {
const props = {firstName: 'Ben', lastName: 'Hector'};
return <Greeting {...props} />;
}
建议:… 构建通用容器时使用,但是多组件使用该属性时可能会混乱。
字符串常量
<MyComponent>Hello world!</MyComponent>
通过props.children获取“hellO world”
2.如上,标签间html未转义。
即可以:
3.JSX 会移除空行和开始与结尾处的空格。标签邻近的新行也会被移除,字符串常量内部的换行会被压缩成一个空格。
jsx
1.可以混合不同类型的子元素,同时用字符串常量和 JSX 子元素。
<div>
Here is a list:
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
2.通过数组形式,返回多个元素。
render() {
// 不需要使用额外的元素包裹数组中的元素
return [
// 不要忘记 key :)
<li key="A">First item</li>,
<li key="B">Second item</li>,
<li key="C">Third item</li>,
];
}
js表达式
1.可以将任何 {} 包裹的 JavaScript 表达式作为子代传递。
<MyComponent>foo</MyComponent>
<MyComponent>{'foo'}</MyComponent>
2.props.children
可以像其它属性一样传递任何数据,而不仅仅是 React 元素。
例如,如果你使用自定义组件,则可以将调用 props.children 来获得传递的子代:
// Calls the children callback numTimes to produce a repeated component
function Repeat(props) {
let items = [];
for (let i = 0; i < props.numTimes; i++) {
items.push(props.children(i));
}
return <div>{items}</div>;
}
function ListOfTenThings() {
return (
<Repeat numTimes={10}>
{(index) => <div key={index}>This is item {index} in the list</div>}
</Repeat>
);
}
效果:
This is item 0 in the list
This is item 1 in the list
This is item 2 in the list
This is item 3 in the list
This is item 4 in the list
This is item 5 in the list
This is item 6 in the list
This is item 7 in the list
This is item 8 in the list
This is item 9 in the list
布尔值、Null 和 Undefined 被忽略
1.false、null、undefined 和 true 都是有效的子代,但它们不会直接被渲染。
2.应用:
<div>
{showHeader && <Header />}
<Content />
</div>
3.JavaScript 中的一些 “falsy” 值(比如数字0),它们依然会被渲染,打印出数字0。
解决:保证&&前面是布尔值。
<div>
{props.messages.length > 0 &&
<MessageList messages={props.messages} />
}
</div>
4.如果你想让类似 false、true、null 或 undefined 出现在输出中,你必须先把它转换成字符串 。