在学习新的框架之前,必须知道的一些基础知识
DOM元素
例:用HTML语法描述按钮(button)
<button class="btn btn-blue">
<em>Confirm</em>
</button>
在 JavaScript 中创建 Virtual DOM 元素(即将HTML转化为JSON对象)
{
type: 'button',
props: {
className: 'btn btn-blue',
children: [{
type: 'em',
props: {
children: 'Confirm'
}
}]
}
}
封装成组件元素
const Button = ({ color, text }) => {
return {
type: 'button',
props: {
className: `btn btn-${color}`,
children: {
type: 'em',
props: {
children: text,
},
},
},
};
}
Button({color:'blue', text:'Confirm'})
即可调用
封装成组件元素的Button用JSON结构描述的结果为:
{
type: Button,
props: {
color: 'blue',
children: 'Confirm'
}
}
加深难度:再度封装
const DangerButton = ({ text }) => ({
type: Button,
props: {
color: 'red',
children: text
}
});
最佳难度:三度封装
const DeleteAccount = () => ({
type: ‘div’,
props: {
children: [{
type: ‘p’,
props: {
children: ‘Are you sure?’,
},
}, {
type: DangerButton,
props: {
children: ‘Confirm’,
},
}, {
type: Button,
props: {
color: ‘blue’,
children: ‘Cancel’
},
}],
}
})
因此,JSX出现,JSX 将 HTML 语法直接加入到 JavaScript 代码中
JSX语法:
const DeleteAccount = () => (
<div>
<p>Are you sure?</p>
<DangerButton>Confirm</DangerButton>
<Button color="blue">Cancel</Button>
</div>
)
将 DeleteAccount 组件通过 Babel 转译成 React代码
var DeleteAccount = function DeleteAccount() {
return React.createElement(
'div',
null,
React.createElement(
'p',
null,
'Are you sure?'
),
React.createElement(
DangerButton,
null,
'Confirm'
),
React.createElement(
Button,
{ color: 'blue' },
'Cancel'
)
);
}
JSX基本语法
JSX 的官方定义是类 XML 语法的 ECMAScript 扩展
1、 XML 基本语法
定义标签时,只允许被一个标签包裹
标签一定要闭合
2、 元素类型
判断首字母是否为小写字母,其中小写首字母对应DOM元素,而组件元素自然对应大写首字母
注释
{/* 节点注释 */}
/* 多行
注释 */
条件注释:<!--[if IE]> <p>Work in IE browser</p> <![endif]-->
3、 元素属性
class 属性改为 className;
for 属性改为 htmlFor
组件元素的属性是完全自定义的属性,例如:
const Header = ({title, children}) => (
<h3 title={title}>{children}</h3>
);
如以上代码,我们就已经给Header组件添加了title属性,调用方法为:
<Header title="hello world">Hello world</Header>
注意点:
- 自定义标签的属性可以传递
- 标签自带的属性无法传递
- 写自定义属性的时候,都由标准写法改为小驼峰写法。
- Boolean 属性
省略 Boolean 属性值会导致 JSX 认为 bool 值设为了 true。要传 false 时,必须使用属性表达式。
例如,<Checkbox checked={true} />
可以简写为 <Checkbox checked />
,反之 <Checkbox checked={false} />
就可以省略 checked 属性。
- 展开属性
若事先知道组件需要的全部属性,JSX书写方式:
const component = <Component name={name} value={value} />;
如果事先不知道要设置哪些 props,那么现在最好不要预先设置:
const component = <Component />;
component.props.name = name;
component.props.value = value;
使用ES6的特性书写:
const data = { name: 'foo', value: 'bar' };
const component = <Component name={data.name} value={data.value} />;
相当于
const data = { name: 'foo', value: 'bar' };
const component = <Component {...data} />;
- 自定义HTML属性
- 如果在 JSX 中往 DOM 元素中传入自定义属性,React 是不会渲染的:
<div d="xxx">content</div>
如果要使用 HTML 自定义属性,要使用 data- 前缀,这与 HTML标准也是一致的:
<div data-attr="xxx">content</div>
然而,在自定义标签中任意的属性都是被支持的:
<x-my-component custom-attr="foo" />
- 以aria- 开头的网络无障碍属性同样可以正常使用:
<div aria-hidden={true}></div>
4、 JavaScript属性表达式
属性值要使用表达式,只要用 {} 替换 “” 即可
// 输入(JSX):
const person = <Person name={window.isLoggedIn ? window.name : ''} />;
// 输出(JavaScript):
const person = React.createElement(
Person,
{name: window.isLoggedIn ? window.name : ''}
);
子组件也可以作为表达式使用:
// 输入(JSX):
const content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
// 输出(JavaScript):
const content = React.createElement(
Container,
null,
window.isLoggedIn ? React.createElement(Nav) : React.createElement(Login)
);
5、 HTML转义
- 直接使用 UTF-8 字符 ©;
- 使用对应字符的 Unicode 编码查询编码;
- 使用数组组装
<div>{['cc ', <span>©</span>, ' 2015']}</div>;
- 直接插入原始的 HTML。
- 提供了 dangerouslySetInnerHTML 属性
<div dangerouslySetInnerHTML={{__html: 'cc © 2015'}} />