felix-cao / Blog

A little progress a day makes you a big success!
31 stars 4 forks source link

React 自定义组件的三种方式及区别 #121

Open felix-cao opened 5 years ago

felix-cao commented 5 years ago

React 专注于 view 层,组件化则是 React 的基础,也是其核心理念之一,一个完整的应用将由一个个独立的组件拼装而成。

自 2013年 React 被开源出来至今,在 React 的发展历史中,先后出现过三种自定义组件的方式:

ES6 是 2015 年 6 月发布出来的, React 是 2013 年 3 月发布出来的,中间间隔了 2 年多。

一、React.createClass

这个是 React 最早使用这个方法来构建一个组件“类”,它接受一个对象为参数,对象中必须声明一个render 方法,render 返回一个组件实例,下面用一个 Button 组件的例子来看看 React.createClass的具体用法:

var React = require('react');
var ReactDOM = require('react-dom');

var myButton = React.createClass({
  getInitialState: function() {
    return {};
  },
  render () {
    return (
      <Button>{ this.props.children }</Button>
    );
  }
});

ReactDOM.render(
   <myButton/>,
   document.getElementById('app')
);

二、类式组件

react 升级到 V 0.13 后开始支持 ES6class 语法,我们可以使用 class App extends React.Component{...} 的方式创建组件,这也是目前官方推荐创建有状态组件的方式。用 ES6 重写上面 Button 组件的例子:

import React from 'react';
import { render } from 'react-dom';
class myButton extends React.component {
  constructor(props) {
     super(props)
     this.state = {}
  }
  render () {
    return (
      <Button>{ this.props.children }</Button>
    );
  }
}

export default myButton;

这里使用 ES6 的 class 的继承机制,去掉了getInitialState 这个 hook 函数,state 的初始化放在构造函数方法 constructor 中声明。

三、函数式组件 又称 无状态组件

React.createClassReact.Component 都可以用来创建有状态的组件,而无状态组件 Stateless ComponentReact 在 v0.14 之后推出的。

它的出现 是因为随着应用复杂度不断提升和组件数量的增加,组件按各自职责被分成不同的类型,于是有一种只负责展示的纯组件出现了,它的特点是不需要管理状态 state,数据直接通过 props 传入,这也符合 React 单向数据流的思想。

对于这种无状态的组件,使用函数式的方式声明,会使得代码的可读性更好,并能大大减少代码量,Arrow Function 则是函数式写法的最佳搭档:

const myButton = (props) => {
  return (
    <Button>{this.props.name}</Button>
  )
}
export default myButton;

四、总结

Facebook 官方早就声明 ES6 React.Component将取代React.createClass。随着 React 不断发展,React.createClass 暴露出一些问题:

相比React.Component可以有选择性的绑定需要的函数,React.createClass会自动绑定函数,这样会导致不必要的性能开销。 React.createClass亲生的 mixinReact.Component不再支持,事实上 mixin 不够优雅直观,替代方案是使用更流行的高阶组件-HOC,如果你的项目还离不开 也可以使用 react-mixin