zoukankan      html  css  js  c++  java
  • 转载 React.createClass 对决 extends React.Component

    先给出结论,这其实是殊途同归的两种方式。过去我们一般都会使用 React.createClass 方法来创建组件,但基于 ES6 的小小语法糖,我们还可以通过 extends React.Component 来创建组件。

    这两种创建方式之间的差别很小,但只有了解这些颇有趣味的区别之后,我们才能做出最适合自己的选择。

    语法区别

    首先,让我们通过两个代码片段和相应的解释来看看到底有哪些语法区别。

    React.createClass

    我们先把新创建的 class 赋给一个常量,并添上 render 函数以完成最基本的组件定义。

    import React from 'react';
    
    const Contacts = React.createClass({  
      render() {
        return (
          <div></div>
        );
      }
    });
    
    export default Contacts;  
    

    React.Component

    接下来把上面 React.createClass 定义的部分转换成 ES6 代码。

    import React from 'react';
    
    class Contacts extends React.Component {  
      constructor(props) {
        super(props);
      }
      render() {
        return (
          <div></div>
        );
      }
    }
    
    export default Contacts;  
    

    从 JavaScript 语言层面来看,我们已经在使用 ES6 中的类了,通常这些 ES6 代码需要使用类似 Babel 的工具转换为 ES5 代码之后才能在浏览器中正常执行。这里我们引入了一个叫 constructor 的东西,因为我们需要在这里调用 super() 函数来为 React.Component 传递属性。

    在这次代码转换中,我们通过继承 React.Component 代替直接调用 React.createClass 的方式,创建了一个叫做“Contacts”的类,使得这段代码中 JavaScript 的味道变得更浓郁了。在整个语法转换的过程中,这一步具有革命性的意义。

    propType 和 getDefaultProps

    这是个关乎如何使用、声明默认属性和类型,以及如何设置给类初始化状态的重要变化。

    React.createClass

    在调用 React.createClass 时,我们添加了一个叫做 propTypes 的对象,只要给它的属性进行赋值就能声明对应属性的类型。 getDefaultProps 这个函数返回了一个对象,这个对象的所有属性将会作为组件的初始化属性。

    import React from 'react';
    
    const Contacts = React.createClass({  
      propTypes: {
    
      },
      getDefaultProps() {
        return {
    
        };
      },
      render() {
        return (
          <div></div>
        );
      }
    });
    
    export default Contacts;  
    

    React.Component

    转换语法之后,我们通过给 Contacts 类添加一个名为 propTypes 属性的方式来达到和上面同样的效果。我认为这种方式比之前更加干净简洁了。

    而 getDefaultProps 函数也变成了一个名为 defaultProps 的属性,注意它仅仅是一个对象而不是“get”函数。我更喜欢这种语法,因为它跳出了 React 的语法规则,变成了原生 JavaScript。

    import React from 'react';
    
    class Contacts extends React.Component {  
      constructor(props) {
        super(props);
      }
      render() {
        return (
          <div></div>
        );
      }
    }
    Contacts.propTypes = {
    
    };
    Contacts.defaultProps = {
    
    };
    
    export default Contacts;  
    

    State 的区别

    这部分的改变相当有趣,首先我们得使用构造函数来完成初始化状态的设置。

    React.createClass

    我们创建了一个叫做 getInitialState 的函数,它只做一件事,那就是返回一个包含初始化状态的对象。

    import React from 'react';
    
    const Contacts = React.createClass({  
      getInitialState () {
        return {
    
        };
      },
      render() {
        return (
          <div></div>
        );
      }
    });
    
    export default Contacts;  
    

    React.Component

    转换以后 getInitialState 函数被抛弃了,我们在 constructor 中像创建初始化属性一样声明了所有状态,我认为这样更加像 JavaScript 并且更少地驱动了“API”(译注:这里“更少地驱动了 API”应该并非原作者本意,但查阅相关文章都未找到合理的中文释义,只得将其直译了)

    import React from 'react';
    
    class Contacts extends React.Component {  
      constructor(props) {
        super(props);
        this.state = {
    
        };
      }
      render() {
        return (
          <div></div>
        );
      }
    }
    
    export default Contacts;  
    

    “this” 的区别

    使用 React.createClass 时 React 会自动帮我们处理函数中的 this 指针,但使用 ES6 的话 this 将会失效。

    React.createClass

    注意,我们在 onClick 属性上绑定了 this.handleClick。当点击事件被触发时,React 会切换到正确的上下文中去执行 handleClick

    import React from 'react';
    
    const Contacts = React.createClass({  
      handleClick() {
        console.log(this); // React Component instance
      },
      render() {
        return (
          <div onClick={this.handleClick}></div>
        );
      }
    });
    
    export default Contacts;  
    

    React.Component

    由于使用了 ES6,这里会有些微不同,属性并不会自动绑定到 React 类的实例上。

    import React from 'react';
    
    class Contacts extends React.Component {  
      constructor(props) {
        super(props);
      }
      handleClick() {
        console.log(this); // null
      }
      render() {
        return (
          <div onClick={this.handleClick}></div>
        );
      }
    

    我们可以像下面这样在行内代码中绑定正确的执行上下文:

    import React from 'react';
    
    class Contacts extends React.Component {  
      constructor(props) {
        super(props);
      }
      handleClick() {
        console.log(this); // React Component instance
      }
      render() {
        return (
          <div onClick={this.handleClick.bind(this)}></div>
        );
      }
    }
    
    export default Contacts;  
    

    除此之外,我们也可以在 constructor 中来改变 this.handleClick 执行的上下文,相对于上一种来说这显然是更加优雅的解决办法,万一将来我们需要改变语法结构,这种方式完全不需要去改动 JSX 的部分:

    import React from 'react';
    
    class Contacts extends React.Component {  
      constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
      }
      handleClick() {
        console.log(this); // React Component instance
      }
      render() {
        return (
          <div onClick={this.handleClick}></div>
        );
      }
    }
    
    export default Contacts;  
    

    Mixins

    如果我们使用 ES6 的方式来创建组件,那么 React mixins 的特性将不能被使用了。

    React.createClass

    使用 React.createClass 的话,我们可以在创建组件时添加一个叫做 mixins 的属性,并将可供混合的类的集合以数组的形式赋给 mixins

    import React from 'react';
    
    var SomeMixin = {  
      doSomething() {
    
      }
    };
    const Contacts = React.createClass({  
      mixins: [SomeMixin],
      handleClick() {
        this.doSomething(); // use mixin
      },
      render() {
        return (
          <div onClick={this.handleClick}></div>
        );
      }
    });
    
    export default Contacts;  
    

    React.Component

    但在 ES6 中,mixins 特性不被支持。

    建议

    Facebook 官方的建议是,等到 ES6 中的类对所有特性有完整支持的时候弃用 React.createClass。但现在,凭感觉去使用吧,它们本质上还是殊途同归的两种方式——说到底它俩不都是类嘛!

    原文地址:https://www.peachis.me/react-createclass-versus-extends-react-component/

  • 相关阅读:
    设计手稿: 搜索引擎
    软件版本介绍
    VS2012中使用编译的Qt-5.1.1静态库开发程序
    POJ2236(并查集)
    Java关键字this的用法总结
    paip.提升用户体验-----c++ gcc 命令在notepad++扩展中的配置..
    MySQL基本查询语句练习
    [置顶] 提升代码内外部质量的22条经验
    mysql 数据库复制表 create table city1 like city;
    两个脚本
  • 原文地址:https://www.cnblogs.com/xiaozhumaopao/p/8311307.html
Copyright © 2011-2022 走看看