React组件与JSX语法

virtual DOM

真实页面对应一个DOM树。在传统页面的开发模式中,每一次需要更新页面的时候,都需要手动操作DOM来进行更新。

传统DOM更新

DOM的操作是十分昂贵的,我们在前端开发中,性能消耗最大的就是DOM操作,而且这部分的代码会让整体项目的代码变得难以维护。React把真实的DOM树转换为JavaScript对象树,也就是virtual DOM

React DOM更新

每一次数据更新后,重新计算Virtual DOM,并和上一次生成的Virtual DOM进行比对,对发生变化的部分进行批量更新。Rect也提供直接的shouldComponentUpdate声明周期回调,来减少数据变化后的不必要的Virtual DOM对比的过程,用来保证性能。

JSX语法

JSXReact有什么关系?简单的来说,React为了方便view层组件化,承载了构建HTML结构化页面的职责,React通过创建于与跟新虚拟元素(virtual DOM)来管理整个Virtual DOM
React创建虚拟元素可以划分为两类,DOM元素(DOM element)与组件元素(component element),分别对应原生的DOM元素和自定义元素,而JSX与创建元素有很大的关系。
JSX的官方定义是类XML语法的ECMAScript扩展。它完美的利用了JavaScript自带的语法和特性,并且使用大家熟悉的HTML语法来创建虚拟元素。可以说,JSX基本语法被XML囊括了,但是也有少许不同的地方。

XML基础语法

使用类XML语法的好处是标签可以任意嵌套,我们可以像HTML一样清晰看到DOM树结构和其属性,比如我们构建一个List组件。

const List = () =>{
  
This is Title
  • list item
}

List的过程就像写HTML一样,只不过它被包裹在JavaScript的方法中,但是在这个过程中需要注意以下几点:

  • 标签一定要闭合
  • 定义标签的时候,只允许被一个标签包裹。所以上面的写法是错误的。
const List = () =>{
  
This is Title
  • list item
This is Title
  • list item
}
元素类型

我们都知道JSX语法中的元素分为DOM元素(DOM element)与组件元素(component element),JSX对应的规则是HTML标签是否为小写字母,其中小写字母对应DOM元素,而逐渐元素自然对应的是首字母大写。

注释

事实上JSX还是JavaScript,依然可以用简单的方法使用注释,唯一需要注意的是,在一个组件的子元素位置使用注释需要{}进行包裹,实例代码如下:

const App = (
  
)
元素属性

JSX中,不论是DOM元素还是组件元素,它们都是有属性的,不同的是,DOM元素的属性是标准规范属性,但是有两个例外--classfor,这是因为在JavaScript中这两个单词是关键词,因此我们这么转换。

  • class属性修改为className
  • for属性改为htmlFor

而组件元素的属性是完全自定义的,也可以理解成组件需要的参数,举个栗子:

const Header = ({title,children})=>{
  

{children}

};
hello world

我们可以对属性进行展开展开,这个应用场景主要是,当我们知道组件的全部属性的时候,使用JSX可以这么写:

//方法一
const component = ;

//方法二
const component = ;
component.props.name = name;
component .props.value = value;

// 方法三:使用ES6特性来提高效率
const data = {name:'foo', value:'bar'};
const component = ;
//方法三可以使用ES6来进行简写
const data = {name:'foo', value:'bar'};
const component = < Component  {...data} />;
javaScript属性表达式

属性值要使用表达式的话,只要使用{}进行替换即可。

//输入(JSX)
const person = 
//输出(JavaScript)
const person = React.createElement (
  person,
  {name:window.isLoggedIn ? window.name:' '}
);

其中子组件也可以作为表达式使用:

//输入(JSX)
const content = {window.idLoggedIn ? 

小结:

  • JSX是一个看起来很像XMLJavaScript语法扩展,这种语法允许你在写JavaScript中写可嵌套的闭合标签。
  • JSXHTML语法很像,可以嵌套,可以自定义属性。
  • JSX允许在闭合标签中使用JavaScript表达式,但是要被{}所包裹
  • JSX中的内联样式也是通过style属性来定义的,但属性值不能是字符串而必须为对象,而且要注意对象中的属性名需要使用驼峰命名法。
  • JSX中,标签子节点内的注释应该写在{}内。
  • JSX中的数组会自动的展开所有的成员,但是需要注意的是,如果数组或是迭代器中的每一项都是HTML标签或是组件的话,那么他们必须要拥有唯一的key属性

React组件

其实对组件的封装很类似与面向对象的思想,交互基本上以操作DOM为主,逻辑上是结构上哪里需要变,我们就操作哪里。此外,对于JavaScript的结构,我们得到了几项规范标准组件的信息。

  • 基本的封装性:尽管说JavaScript没有真正的面向对象的方法,但是我们还是可以通过实例化的方法来制造对象。
  • 简单的生命周期:最明显的两个方法是:constructordestroy,代表了组件的挂载卸载的过程,但是除此之外,其他过程(如更新时的声明周期)并没有体现。
  • 明确的数据流动:这里的数据指的是地道用组件的参数。一旦确定参数的值,就会解析传进来的参数,根据参数的不同做出不同的响应,从而得到渲染的结果。

Web Components规范:这个规范想要同意web端关于组件的定义,它可以通过定义Custom Elements(自定义元素)的方式来统一组件。每一个自定义元素可以定义自己对外提供的属性、方法、还有事件,内部可以像写一个页面一样,专注于实现功能来完成对组件的封装。

Web Components组成

Web Components定义了一切我们想要的组件化的概念,其中HTML Template定义了之前的模板概念,Customer Element定义了组件的展现形式,shadow DOM定义了组件的作用域范围,可以包括样式,HTML Imports提出了新的引入方式。

React组件的构建

React组件即为组件元素:组件元素描述成纯粹的Json对象,意味着可以使用方法或是类来构建。React组件即为组件元素,组件基本上由3个部分组成-- 属性(props)、状态(state)以及生命周期方法,这里我们从一张图来简单的概括React

React组件的组成

React组件可以接受参数,也可以有自身的状态,一旦接受到的参数或是自身的状态有所改变,React组件就会执行相对应的生命周期的方法,最后渲染,整个过程完全符合传统组件所定义的组件职责。
React和web component的关系
Reactweb component传达的理念是一致的,但是二者的实现方式是不同的,

  • React自定义元素的库是自己构建的,与web component规范是不一致的
  • React渲染过程包含了模板的概念,也就是之前说的JSX
  • React组件的实现均在方法和类中,因此做到了相互的隔离,但是不包含样式。
  • React引用方式遵循ES6标准

官方在React组件构建上提供了3种不同的方法:React.createClass,ES6 classes 和无状态函数。
React.createClass方法是构建组件最传统,也是兼容性最好的方法,实例代码如下:

const Button = React.createClass({
  getDefaultProps(){
    return {
      color:'red',
      text:'cancle',
    };
  },
  render(){
    const {color, text} = this.props;
    return (
      
    );
  }
});

当组件需要调用Button组件的时候,只需要写 ); } }

这里的直观感受是从调用内部方法变成了类来实现,与createClass的结果相同的是,调用类实现的组件会创建实例对象。在React组件开发中,常用的方式是将组件拆分到合理的粒度,用组合的方式合成业务组件。

无状态函数

使用无状态函数构建的组件称为无状态组件,这样的写法比较受官方推崇。我们看一下示例代码:

function Button({color = 'blue',text = 'confirm'}){
  return (
    
  );
}

无状态组件只传入propscontext两个参数;也就是说,它不存在state,也没有生命周期方法,组件本身即上面两种React组件构建方法中的render方法。不过,像propTypesdefaultProps还是可以通过向方法设置静态属性来实现。
我们使用React实现Tabs组件:

import React,{Component,PropType} from 'react';

class Tabs extends Component {
  constructor(props){
    super(props);
  }
  //...
  render(){
    return 
} }; export defaults Tabs;

你可能感兴趣的:(React组件与JSX语法)