AntDesign-React与VUE有点不一样,第一篇深入了解React的概念之一:JSX

AntDesign-React与VUE有点不一样,第一篇深入了解React的概念之一:JSX

一、什么是JSX

使用JSX声明一个变量(REACT当中的元素):

const element =<h1>Hello,world!</h1>;

JSX是一种JavaScript的语法扩展。我们推荐在REACT中使用JSX来描述用户界面,JSX乍一看起来可能比较像是模板语言,但事实上完全是JavaScript内部实现的。

二、为什么要使用JSX

传统的MVC是将模板房子其他地方,比如<script>标签或者模板文件,再在JS中通过梦中手段引用模板。按照这种思路,想想多少次我们面对四处分散的模板片段不知所措?纠结模板引擎,纠结模板存放位置,纠结如何引用模板…………下面是一段REACT官方的看法:

We strongly believe that components are the right way to separate concerns rather than "templates" and "display logic." We think that markup and the code that generates it are intimately tied together. Additionally, display logic is often very complex and using template languages to express it becomes cumbersome.
简单来说,REACT认为组件才是王道,而组件是模板紧密关联的,JSX这种语法,就是为了把HTML模板直接嵌入到JS代码里面,这样就做到了模板和组件关联,但是JS不支持这种包含HTML的语法,所有需要通过工具将JSX编译输出程JS代码才能使用。
npm install babel-loader --save-dev

三、载入方式

JSX目前有两种方法载入。

1、内联方式载入

<script type="text/babel">
    ReactDOM.render(
      <h1>hello landv.cn</h1>,
      document.getElementById('example')
    );
</script>

2、外联方式载入

即将JSX代码单独放在一个.JSX文件中。

ReactDOM.render(
     <h1>hello landv.cn</h1>,
     document.getElementById('example')
);

然后在页面上通过下面的方式引入这个.jsx文件。

<script type="text/babel" src="hello.jsx"></script>

四、在jSX中使用表达式

可以任意地在JSX当中使用JavaScript表达式,在JSX当中的表达式要包括在大括号里(个人理解就是写在JS里的HTML里面的JS需要{}大括号)。

// 定义一个函数,返回传入的名字的拼写后的结果
function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}
// 定义一个数据类型为对象的常量
const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};
// 使用JSX语法来定义一个html标签(所以element为小写开头)
const element = (
  <h1>
    Hello, {formatName(user)}!
  </h1>
);
// 渲染这个html标签
ReactDOM.render(
  element,
  document.getElementById('root')
);

注意:

1、我们书写JSX的时候一般都会带上换行和缩进,这样就可以增强代码的可读性。

2、与此同时,我们同样推荐在JSX代码的外面扩上一个小括号,这样可以防止分号自动插入的BUG

五、JSX本身其实也是一种表达式

在编译之后呢,JSX其实会被转换为普通的JavaScript对象。
这也就意味着,你其实在IF或者FOR语句里面使用JSX,将它赋值给变量,当做参数传入,作为返回值都可以:
// 定义一个函数,如果有传参数进来就把名字拼写好返回,否则就返回陌生人
function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

六、JSX属性

你可以使用引号来定义以字符串为值的属性:

const element = <div tabIndex="0"></div>;

也可以使用大括号来定义以JavaScript表达式为值的属性:

const element = <img src={user.avatarUrl}></img>;
切记使用了大括号包裹的 JavaScript 表达式时就不要再到外面套引号了。JSX 会将引号当中的内容识别为字符串而不是表达式。(不要src="{user.avatarUrl}",会以为src为{user.avatarUrl})

七、JSX嵌套

如果JSX标签是闭合式的,那么你需要在结尾处用/>,就好像XML/HTML一样:
const element = <img src={user.avatarUrl} />;

JXS标签同样可以相互嵌套:(当换行和缩进的时候,使用括号包住它们)

const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);

警告:

因为JSX的特性更接近JavaScript而不是HTML,所以REACT DOM使用camelCase小驼峰命名来定义属性的名字,而不是使用HTML的属性命名。(概括就是:JSX使用小驼峰命名定义属性的名称)

例如,class编程了className,而tabindex则对应着tabIndex.

八、JSX防注入攻击

你可以放心地在JSX当中使用用户输入:

const title = response.potentiallyMaliciousInput;
// 直接使用是安全的:
const element = <h1>{title}</h1>;

REACT DOM在渲染之前默认会过滤所有传入的值,它可以确保你的引用不会被注入攻击。所有的内容在渲染之前都被转换成了字符串。这样可以有效的防止XSS(跨站脚本)攻击。

九、HTMl转义

REACT会将所有要显示到DOM的字符串转义,防止XSS。所以如果JSX中包含转义后的实体字符串比如&copy:(©)最后显示到DOM中不会被正确显示,因此REACT自动吧&copy;中的特殊字符转义了。有几种解决方法:

  • 直接使用UTF-8字符©
  • 使用对应字符的Unicode编码,查询编码
  • 使用数组组装<div>{['cc ', <span>&copy;</span>, ' 2019']}</div>
  • 直接插入原始的HTML
<div dangerouslySetInnerHTML={{__html: 'cc &copy; 2019'}} />

十、JSX代表Objects

Babel转译器会把JSX转换成一个名为React.createElement()的方法调用。

下面两种代码的作用是完全相同的:

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

React. createElement()这个方法首先会进行一些避免BUG的检查,之后返回一个类似下面例子的对象:

// 注意: 以下示例是简化过的(不代表在 React 源码中是这样)
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world'
  }
};

这样的对象被成为“REACT元素”。它代码所有你在屏幕上看到的东西。

REACT通过读取这些对象来构建DOM并保持数据内容一致。

十一、注释

在JSX里使用注释也很简单,就是沿用JavaScript,唯一要注意的是在一个组件的子元素位置使用注释要用{}包起来。

var content = (
  <Nav>
      {/* child comment, put {} around */}
      <Person
        /* multi
           line
           comment */
        name={window.isLoggedIn ? window.name : ''} // end of line comment
      />
  </Nav>
);

十二、自定义HTML属性

如果在JSX中使用的属性不存在与HTML的规范中,这高属性会被忽略。如果使用自定义属性,可以用data-前缀。

可访问性属性的前缀aria-也是支持的。

支持的标签和属性

如果你要使用的某些标签或属性不在这些支持列表里面就可能被REACT忽略,必须哟使用的话可以提ISSue,或者用前面提到的dangerouslySetInerHTML.

十三、属性扩展

有时候你需要给组件设置多个属性,你不想一个个写下这些属性,或者有时候你甚至不知道这些属性的名称,这时候spread attributes的功能就很有用了。

比如:

var props = {};
props.foo = x;
props.bar = y;
var component = <Component {...props} />;

props对象的属性会被设置程Component的属性。

属性也可以被覆盖:

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

写在后面的属性值会被覆盖前面的属性。

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

参考资料

  1. React 官方中文文档
  2. React 中文文档
  3. React - JSX语法详解(附样例)

对对对

posted @ 2019-12-06 10:52  landv  阅读(3293)  评论(0编辑  收藏  举报