React以及组件创建
JSX 最简单的语法的可能是这样的:
const greetWord = <span>HI</span>; |
可以看到,它既然不是字符串,也不是变量。而是一个不带双引号的、HTML标签与文本内容混合在一起的格式。
要想在页面显示上面的内容,我们必须把它放入一个组件中。首先,定义一个组件,再利用 {}
符号,把上面的 jsx 内容插入组件中:
import React from 'react'; |
当然,这里的 <div>{greetWord}</div>
也可以替换成 greetWord
,只需要保证 return 的内容是被HTML标签包裹的即可。这样,Greet
组件
或者,你无需在前面定义 jsx,即可以直接在组件里插入内容:
class Greet extends Component { |
为了代码的可读性,当 return 的内容涉及多行时,我们会把分成多行:
class Greet extends Component { |
但运行时,却发现报错,提示返回的是非法格式。由于js中 return 后面会自动补 ;
,所以这里返回的是 undefined
。我们尝试改进:
class Greet extends Component { |
在 return 后面紧跟着 <div>
,这样就能正常渲染组件了。不过,官方则推荐使用 ()
包裹 return 的内容,即:
class Greet extends Component { |
组件中 {}
里的内容非常灵活,可以是任意的JavaScript表达式,变量、函数、运算都可以,如:
function inputName() { |
渲染组件
前面主要说组件的创建,而要渲染这个组件,则需要引入 react-dom
库,如:
import React from 'react'; |
这样,组件 Greet
便在 id 为 root 的节点下进行了渲染。
有的时候,我们需要针对条件来隐藏(不渲染)组件,你只需要 return null
即可。比如 LoadingTips 加载组件,当父组件的ajax请求完毕后,可根据传递的 props.load
属性,来决定 LoadingTips 组件的渲染与否:
function LoadingTips(props) { |
创建组件
目前看来,react组件的创建主要分为三大类,即:
- 纯函数创建无状态组件-SFC
- ES5-React.createClass
- ES6-extends React.Component
SFC
SFC,即Stateless Functional Component,也被叫做 无状态功能组件,比如,我们文章开头提到的组件,就是采用这种形式编写的。
SFC组件通常被用来单纯展示一些UI界面,这种组件的数据来源主要是通过 props
,不会涉及任何 state
的操作,所以被称为 无状态组件。可通过如下语法创建:
var React = require('react'); |
在上面的代码中,InputName
就是一个 SFC组件。
作为纯展示的组件,SFC组件的特点是不会被实例化,性能大幅度提升。因为没有状态,不能使用 this.state
来访问状态数据。只能通过 this.props
访问父级传递的数据,并且照搬显示该 this.props
,因此,不会有副作用。
介于代码简洁、性能高效以及无副作用,所以,提倡在大型应用中,尽可能把组件分割成无状态组件。
React.createClass
ES5创建组件的方式则是采用如下语法:
const React = require('react'); |
这里可以看到,组件 props
和 state
的相关方法都定义在组件内部。并且因为存在实例化过程,我们也可以通过 this.props
和 this.state
来访问组件的数据。
相应地,我们还可以在组件内添加生命周期方法,并进行相关处理。
另外,对于使用 React.createClass
这种形式创建的组件,react做了内部处理。组件里面的所有函数都会自动进行this绑定。除此之外,这种形式的组件,还支持 mixin 功能。
extends React.Component
要说目前最流行的创建react组件语法,当然是ES6类结合继承的形式:
import React, {Component} from 'react' |
extends React.Component
这种形式创建的组件,把 类型检测 和 默认属性 “外置” 了,因为 ES6 的子类一开始没有 this 对象,通过在子类的构造函数中调用 super
方法来获取父级的引用。
而在里面传入 props
参数,则表明可在 constructor
构造函数中通过 this.props
来访问父组件挂载的属性。但倘若你是在 render()
函数里访问 this.props
,则 super
方法无需传入 props
参数:
class Greet extends Component { |
构造函数里除了 super
方法,我们还需要在 this 上设置了初始的 state
属性。
但是,这种形式的组件有个缺点。由于我们是点 button 按钮,则事件内部的 this 实际上是 button DOM。因此,这种形式创建的组件,其中的的事件函数句柄不会自动绑定当前实例的 this,所以,我们还得在构造函数里手动绑定 this。
另外,它还不支持react的 mixin 功能。但可以考虑用封装高阶组件进行代替。