JSX学习

深度学习JSX–JSX in deep

JSX是一种JavaScript的延伸,看起来好像XML。你可以在React里使用一种简单的JSX语法的变形。

Why JSX?

虽然你也可以在React中使用原生的JavaScript,但是我们还是建议你使用JSX。因为它是一种更简洁直接和熟悉的语法去构建带属性的树结构。
不管是对设计者还是开发者都对它更熟悉。
它的标准的开闭标签有助于阅读一大颗树。
它不会改变JavaScript语义。

HTML Tags vs. React Components

React既可以render HTML 标签(字符串),也可以render React Component(classes)。
render HTML 标签,可以使用JSX里的小写标签:

var myDivElement=<div className='foo' />;
ReactDOM.render(myDivElement,document.getElementById('example'));

render React组件,首先使用React.createClass()创建组件,大写开头,然后再render。

var MyComponent=React.createClass({/*...*/});
var myElement=<MyComponent someProperty={true} />;
ReactDOM.render(myElement,document.getElementById('example'));

注意,JSX是JavaScript,所以class,for是保留字,不能作为属性名来使用,我们推荐使用className,htmlFor来作为属性名。

变形

可以在这里输入JSX代码来看看转换的原生JavaScript代码。
首先,React JSX是从一种类XML语言转换成JavaScript代码的。XML元素,属性和子节点都会转换为JS的createElement函数参数。如下:

var Nav;
var app=<Nav color='red' />;//JSX input
var app=React.cretaElement(Nav,{color:'red'});//JS output

JSX允许使用XML的语法指定子节点,如下:

var Nav,Profile;
var app=<Nav color='red'><Profile>click</Profile></Nav>;//JSX input
var app=React.createElement(
    Nav,
    {color:'red'},
    React.createElement(Profile,null,"click")
);//JS output

JSX会推断类的displayName如果不定义的话:

var Nav=React.createClass({});//JSX input
var Nav=React.createClass({displayName:”Nav”});

JSX表达式在React会被认为是一个ReactElement

命名空间组件

如果你在构建一个有很多孩子的组件(比如一个form),你可能陷入下面这种尴尬的境地:

var Form=myFormComponent;
var FormRow=Form.Row;
var FormLable=Form.label;
var FormInput=Form.Input;
//不得不声明大量变量

var app=(
    <Form>
        <FormRow>
            <FormLabel />
            <FormInput />
        </FormRow>
    </Form>
);

为了避免这种尴尬的境地,命名空间组件允许某个组件把其他组件作为属性:
var Form = MyFormComponent;

var App = (
  <Form>
    <Form.Row>
      <Form.Label />
      <Form.Input />
    </Form.Row>
  </Form>
);
//使用命名空间组件避免声明大量变量

为了做到命名空间组件,你必须声明某个组件的某个属性为一个组件:

var Form=React.createClass({...});

var Form.Row=React.createClass({...});
var Form.Label=React.createClass({...});
var Form.Input=React.createClass({...});

JSX会这么处理你的代码:

var app=(
    React.createElement(Form,null,
        React.createElment(Form.Row,null,
           React.createElement(Form.label,null),
           React.createElement(Form.Input,null)
        )
    )
)

这个功能需要v0.11及以上版本

JavaScript表达式

属性表达式

把JavaScript表达式圈在一对花括弧{}里会被解释成属性。例:

var person=<Person name={window.isLoggedIn?window.name:''} />;//JSX input

var person=React.createElement(
    Person,
    {name:window.isLoggedIn?window.name:''}
);//JS output
Boolean属性

如果你定义了一个属性但是没有指定它的值那么JSX会认为这个属性的值为true。所以如果一个属性值为false时必须指定attr:{false}或者不定义这个属性。boolean属性往往会出现在HTML表单元素中。

<input type="button" disabled />;
<input type="button" disabled={true} />;
//这两条等价,用于使一个按键失效

<input type="button" />;
<input type="button" disabled={false} />;
//这两条等价,按键不失效
子节点表达式

同样,JavaScript表达式也可用来表达子节点:

var content=<Container>{window.isLoggedIn?<Nav />:<Login />}</Container>;
//JSX input

var content=React.createElement(
    Container,
    null,
    window.isLoggedIn?React.createElement(Nav) : 
          React.createElement(Login);
);
JS output
注释

JSX注释就是JavaScript里的注释,要注意的就是就是在注释与子元素并行时要使用{}

var content=(

JSX传播属性(spread Attribute)

传播语法,点击查看

如果你知道你要指定的组件的所有属性,那很简单:

var component=<Component foo={x} bar={y} />;
可变的属性是bad

如果你不知道你想要指定的属性,你可能会想在后面把属性赋给对象(组件)本身。

var component=<Component />;
conponent.props.foo=x;//bad
conponent.props.bar=y;//also bad

这样是不好的,因为我们一开始无法正确解析组件的属性节点。引入原文:

This is an anti-pattern because it means that we can’t help you check the right propTypes until way later. This means that your propTypes errors end up with a cryptic stack trace.

The props should be considered immutable. Mutating the props object somewhere else could cause unexpected consequences so ideally it would be a frozen object at this point.

传播属性

你可以使用JSX里的spread attribute

var props={}
props.foo=x;
props.bar=y;
var component=<Component {...props} />;//会自动展开的意思吧

你可以反复使用这个语法,也可以跟其他的属性结合,不过顺序很重要,同名的属性以后面出现的为准。

var props={foo:'default'};
var component=<Component {...props} fop={'override'} />;
console.log(component.props.foo);//override

操作符是ES6中新支持的语法。传播语法,点击查看

JSX陷阱

JSX看起来像HTML可是有一些不同你可能会感到迷惑。

HTML实体

在JSX里,你可以通过字面量文本插入HTML实体,像这样:
<div>First &middot; Second</div>
如果你想用变量(表达式)来显示一个HTML,你可能会陷入双重转移的问题。以为React会自动转义你想显示的字符串。这样是为了避免XSS攻击。比如:<div>{'First &middot; Second'}</div>会显示“First · Second”。
避开这个陷阱的方法有:

  • 直接写Unicode字符,像这样<div>{'First · Second'}</div>,这种方法必须保证文件是utf-8编码的并可以获取utf-8字符集
  • 更安全的方式是通过String.fromCharCode(code)取得字符,<div>{'First'+String.fromCharCode(183)+' Second'}</div>
  • 你可以混合字符串和JSX元素组成数组,每个数组里的JSX元素都必须有一个唯一的key<div>{['First',<span key="middot">&middot;</span>,' Second']}</div>
  • 最后一种比较吓人的做法dangerouslySetInnerHTML <div dangerouslySetInnerHTML={{__html:'First &middot;Second'}} />
自定义HTML属性

如果你想在原生的HTML元素上使用一个自定义属性,那么应该加上前缀data-:
<div data-custom-attribute="foo" />
然而在自定义的元素上,任何属性命名都是可以的<x-my-component custom-attribute="foo" />
网页无障碍属性应该以aria-开头<div aria-hidded={true} />

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值