深入JSX
HTML标签和React组件
React既可以渲染HTML标签,也可以渲染React组件。
在JSX语法中,html标签一般以小写字母打头,如:
var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.getElementById('example'));
在React组件中,一般是先定义一个以大写字打头的本地变量,使用时在<>中写上变量名即可,如下
var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
ReactDOM.render(myElement, document.getElementById('example'));
注: jsx也属于javascript,class和for两个属性为javascript的关键字,在定义 React组件时,应将其分别写成className和htmlFor。
将React jsx转化成javascript
JSX语法写成的语句,都会被转化成原生的javascript里的xml元素,其属性和子节点将作为参数传递给React.createElement方法。如
var Nav;
// Input (JSX):
var app = <Nav color="blue" />;
// Output (JS):
var app = React.createElement(Nav, {color:"blue"});
定义 了一个名字为Nav的React组件。通过jsx可以直接写成:var app = < Nav color=”blue” />; 与纯javascript写的:var app = React.createElement(Nav, {color:”blue”}); 意思是一样的。
JSX也允许指定子节点,如
var Nav, Profile;
// Input (JSX):
var app = <Nav color="blue"><Profile>click</Profile></Nav>;
// Output (JS):
var app = React.createElement(
Nav,
{color:"blue"},
React.createElement(Profile, null, "click")
);
当组件的displayName属性没有定义时,其默认值为变量名,如
// Input (JSX):
var Nav = React.createClass({ });
// Output (JS):
var Nav = React.createClass({displayName: "Nav", });
Namespaced 组件
如果定义一个组件有许多个子组件,比如form,必须得声明多个变量,如
// Awkward block of variable declarations
var Form = MyFormComponent;
var FormRow = Form.Row;
var FormLabel = Form.Label;
var FormInput = Form.Input;
var App = (
<Form>
<FormRow>
<FormLabel />
<FormInput />
</FormRow>
</Form>
);
这样看起来很麻烦,为了简单和方便,可以使用namespaced 组件。定义时可将子组件定义为父组件的属性,如下
var MyFormComponent = React.createClass({ ... });
MyFormComponent.Row = React.createClass({ ... });
MyFormComponent.Label = React.createClass({ ... });
MyFormComponent.Input = React.createClass({ ... });
使用时,可通过如下方式
var Form = MyFormComponent;
var App = (
<Form>
<Form.Row>
<Form.Label />
<Form.Input />
</Form.Row>
</Form>
);
JSX能正确编译代码:
var App = (
React.createElement(Form, null,
React.createElement(Form.Row, null,
React.createElement(Form.Label, null),
React.createElement(Form.Input, null)
)
)
);
该功能只在V0.11及以上版本提供。
javascript表达式
表达式 属性
JSX语法中,使用javascript表达式作为属性值 时,必须将表达式以{}括起来,而不能直接用”“
// Input (JSX):
var person = <Person name={window.isLoggedIn ? window.name : ''} />;
// Output (JS):
var person = React.createElement(
Person,
{name: window.isLoggedIn ? window.name : ''}
);
boolean属性
JSX 中,如果不写某个属性的值,那么其值默认为true。 即如果想要某个属性值 为true,要么不赋给它值 ,要么使用{true},如果想要某个属性值 为false,要么不写该属性,要么将其值设置为{false},比如给html里的form标签设置disabled, required,checked,readonly属性时:
// These two are equivalent in JSX for disabling a button
<input type="button" disabled />;
<input type="button" disabled={true} />;
// And these two are equivalent in JSX for not disabling a button
<input type="button" />;
<input type="button" disabled={false} />
子节点
也可以通过javascript表达式增加子节点,如
// Input (JSX):
var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
// Output (JS):
var content = React.createElement(
Container,
null,
window.isLoggedIn ? React.createElement(Nav) : React.createElement(Login)
);
添加注释
// 注释一行
/* */注释一段代码。
但需要特别注意的是:如果在标签子节点前添加注释时,需要将注释以{}包围。如
var content = (
<Nav>
{/* child comment, put {} around */}
<Person
/* multi
line
comment */
name={window.isLoggedIn ? window.name : ''} // end of line comment
/>
</Nav>
);
JSX传播属性
如果事先知道组件的所有属性值,可以如下使用JSX:
var component = <Component foo={x} bar={y} />;
最好不要先声明组件,再声明其属性值,类似如下的声明最好不要用:
var component = <Component />;
component.props.foo = x; // bad
component.props.bar = y; // also bad
可通过如下方式声明:
var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;
对象props的属性值是复制给Component的属性的,因此是不可变的。**注意使用…操作符(ES6数组中也支持…操作符)**props可以多次使用,也可以与其他属性一起使用。 属性赋值的顺序很重要,后赋值的属性会覆盖之前赋值的属性。
var props = { foo: 'default' };
var component = <Component {...props} foo={'override'} />;
console.log(component.props.foo); // 'override'
JSX进阶
JSX看起来像html但与html有些许不同。
HTML特殊字符
可以直接在JSX中插入HTML特殊字符:
<div>First · Second</div>
React会转义所有的字符串来防止XSS攻击,因此如果需要动态展示HTML特殊字符,在{}中写入转义字符,最后可能并不能正确显示,如
// Bad: It displays "First · Second"
<div>{'First · Second'}</div>
如果需要在{}中展示html特殊字符有如下几种办法:
- 最简单的方法,直接在javascript中写入特殊字符,不使用转义,但是必须确保文件以UTF-8格式保存,并且浏览器能正确显示
<div>{'First · Second'}</div>
- 最安全的做法,直接在javascript中写入其unicode,如下:
<div>{'First \u00b7 Second'}</div>
<div>{'First ' + String.fromCharCode(183) + ' Second'}</div>
- 也可以使用数组的方式,如下
<div>{['First ', <span>·</span>, ' Second']}</div>
- 也可以直接插入原始的HTML,如下:不推荐。
<div dangerouslySetInnerHTML={{__html: 'First · Second'}} />
定制的HTML属性
如果向HTML元素中传入一些自定义的属性,React并不会对其进行渲染。如果需要使用自定义属性,最好加上data-前缀
<div data-custom-attribute="foo" />
如果是在自定义元素上使用自定义属性也是支持的,属性前面不需要加data-前缀。
<x-my-component custom-attribute="foo" />
web相关的属性即以aria-前缀的属性能够被react正确渲染,如:
<div aria-hidden={true} />
链接:https://www.zybuluo.com/ttingtu/note/249363
参考资料:
- http://facebook.github.io/react/docs/jsx-in-depth.html
- http://facebook.github.io/react/docs/jsx-spread.html
- http://facebook.github.io/react/docs/jsx-gotchas.html