这篇文章主要介绍了 JavaScript 的 React 框架中的 JSX 语法学习入门教程, React 是由 Facebook 开发并开源的高人气 js 框架, 需要的朋友可以参考下
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
什么是 JSX?
在用 React 写组件的时候,通常会用到 JSX 语法,粗看上去,像是在 Javascript 代码里直接写起了 XML 标签,实质上这只是一个语法糖,每一个 XML 标签都会被 JSX 转换工具转换成纯 Javascript 代码,当然你想直接使用纯 Javascript 代码写也是可以的,只是利用 JSX,组件的结构和组件之间的关系看上去更加清晰。
- var MyComponent = React.createClass({
- /*...*/
- });
- var myElement = <MyComponent someProperty = {
- true
- }
- />;
- React.render(myElement, document.body);
- /
一个 XML 标签,比如 <MyComponent someProperty={true} /> 会被 JSX 转换工具转换成什么呢?
比如:
- var Nav = React.createClass({
- /*...*/
- });
- var app = <Nav color = "blue" > <Profile > click < /Profile></Nav > ;
会被转化为:
- var Nav = React.createClass({/*...*/});
- var app = React.createElement(
- Nav,
- {color:"blue"},
- React.createElement(Profile, null, "click")
- );
那么也就是说,我们写一个 XML 标签,实质上就是在调用 React.createElement 这个方法,并返回一个 ReactElement 对象。
- ReactElement createElement(
- string/ReactClass type,
- [object props],
- [children ...]
- )
这个方法的第一个参数可以是一个字符串,表示是一个 html 标准内的元素,或者是一个 ReactClass 类型的对象,表示我们之前封装好的自定义组件。第二个参数是一个对象,或者说是字典也可以,它保存了这个元素的所有固有属性(即传入后基本不会改变的值)。从第三个参数开始,之后的参数都被认作是元素的子元素。
JSX 转化器
要把带有 JSX 语法的代码转化为纯 Javascript 代码,有多种方式,对于内联与 HTML 中的代码或者是未经过转化的外部文件,在 script 标签中要加上 type="text/jsx",并引入 JSXTransformer.js 文件即可,不过这种方式并不建议在生产环境使用,建议的方法是在代码上线前就将代码转换好,可以使用 npm 全局安装 react-tools:
- npm install -g react-tools
并使用命令行工具转化即可(具体用法可以参考 jsx -h):
- jsx src/ build/
如果使用自动化工具,比如 gulp 的话,可以使用相应插件 gulp-react。
HTML 模板中使用 JS
在 HTML 模板中使用 JS 非常方便,只需要用大括号把 JS 代码括起来即可。
- var names = ['Alice', 'Emily', 'Kate'];
- React.render(
- <div>
- {
- names.map(function (name) {
- return <div>Hello, {name}!</div>
- })
- }
- </div>,
- document.getElementById('example')
- );
编译出来就变成了这样:
- var names = ['Alice', 'Emily', 'Kate'];
- React.render(
- React.createElement("div", null, names.map(function (name) {
- return React.createElement("div", null, "Hello, ", name, "!")
- }) ),
- document.getElementById('example')
- );
要注意的是,大括号实际就是一个变量输出表达式,JSX 最终就是直接把花括号中的内容作为 React.createElement 的第三个参数直接传入了(没有任何修改直接传入),所以其中只能放一行表达式,并且任何不能直接作为第三个参数的写法都是错的,那么你这样写就是错的:
- React.render(
- <div>
- {
- var a = 1;
- names.map(function (name) {
- return <div>Hello, {name}!</div>
- })
- }
- </div>,
- document.getElementById('example')
- );
因为很明显其中花括号内的内容直接放在第三个参数上,语法不对。
这么写也是错的:
- React.render(
- <div>
- {
- var a = 1;
- }
- </div>,
- document.getElementById('example')
- );
因为 React.createElement("div", null, var a = 1;) 是语法错误。
那么你也可以理解为什么大括号中的 js 表达式不能有分号结尾了吧。
需要注意的是,如果你在属性中输出 JS 变量,是不能加引号的,不然会被当做字符串而不被解析。
应该是这样:
- <a title={title}>
- 链接
- </a>
要创建一个 HTML 标准中存在的元素,直接像写 HTML 代码一样即可:
- var myDivElement = <div className="foo" />;
- React.render(myDivElement, document.body);
不过需要注意的是 class 和 for 这两个属性,JSX 语法最终是要被转换为纯 Javascript 的,所以要和在 Javascript DOM 中一样,用 className 和 htmlFor。
还有一点是,在创建 HTML 标准内的元素时,JSX 转化器会丢弃那些非标准的属性,如果一定要添加自定义属性,那么需要在这些自定义属性之前添加 data - 前缀。
- <div data-custom-attribute="foo" />
命名空间式组件
比如开发组件的时候,一个组件有多个子组件,你希望这些子组件可以作为其父组件的属性,那么可以像这样用:
- var Form = MyFormComponent;
- var App = (
- <Form>
- <Form.Row>
- <Form.Label />
- <Form.Input />
- </Form.Row>
- </Form>
- );
这样你只需将子组件的 ReactClass 作为其父组件的属性:
- var MyFormComponent = React.createClass({...
- });
- MyFormComponent.Row = React.createClass({...
- });
- MyFormComponent.Label = React.createClass({...
- });
- MyFormComponent.Input = React.createClass({...
- });
而创建子元素可以直接交给 JSX 转化器:
- var App = (
- React.createElement(Form, null,
- React.createElement(Form.Row, null,
- React.createElement(Form.Label, null),
- React.createElement(Form.Input, null)
- )
- )
- );
该功能需要 0.11 及以上版本
Javascript 表达式
在 JSX 语法中写 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)
- );
不过要注意的是,JSX 语法只是语法糖,它的背后是调用 ReactElement 的构造方法 React.createElement 的,所以类似这样的写法是不可以的:
- // This JSX:
- < div id = {
- if (condition) {
- 'msg'
- }
- } > Hello World ! </div>
- / / Is transformed to this JS: React.createElement("div", {
- id: if (condition) {
- 'msg'
- }
- },
- "Hello World!");
可以从转化后的 Javascript 代码中看出明显的语法错误,所以要不用三目运算符,要不就这样写:
- if (condition) <div id='msg'>Hello World!</div>
- else <div>Hello World!</div>
传播属性(Spread Attributes)
在 JSX 中,可以使用... 运算符,表示将一个对象的键值对与 ReactElement 的 props 属性合并,这个... 运算符的实现类似于 ES6 Array 中的... 运算符的特性。
- var props = {
- foo: x,
- bar: y
- };
- var component = <Component {...props
- }
- />;
- /
这样就相当于:
- var component = <Component foo = {
- x
- }
- bar = {
- y
- }
- />
- /
它也可以和普通的 XML 属性混合使用,需要同名属性,后者将覆盖前者:
- var props = {
- foo: 'default'
- };
- var component = <Component {...props
- }
- foo = {
- 'override'
- }
- />;
- console.log(component.props.foo); / / 'override'
来源: http://www.phperz.com/article/17/0216/266820.html