ReactJs组件语法,有什么区别?

时间:2016-07-02 11:03:00

标签: javascript reactjs

我正在学习Reactjs,我正在尝试编写一个基本组件,任何人都可以告诉我为什么这个组件语法:

import React, { Component } from 'react';
export default class AboutPage extends Component {
render: function() {
    const { page } = this.props;
    return (
        <div className="blog-post">
            <h2 className="blog-post-title">{page.title.rendered}</h2>
            <div dangerouslySetInnerHTML={this.createMarkup(page.content.rendered)} />
        </div>
    );
  }
}

这个组件有什么不同吗?

var HelloMessage = React.createClass({
render: function() {
    return <div>Hello {this.props.name}</div>;
  }
});

为什么使用export default class代替var HelloMessage = React.createClass({

3 个答案:

答案 0 :(得分:3)

首先,还有一个你没有提到的选项:

export default function AboutPage(props) {
  const { page } = props;
  const pageContentMarkup = createMarkup(page.content.rendered);
  return (
    <div className="blog-post">
      <h2 className="blog-post-title">{page.title.rendered}</h2>
      <div dangerouslySetInnerHTML={pageContentMarkup} />
    </div>
  );

这个非常简洁,强调你的组件是无状态的。

其次,类语法显然不允许使用mixins。有人说这是一个功能,而不是一个bug,我们实际上应该远离mixin。

Dan Abramov makes an argument mixins不能很好地构成,并提出更高阶的组件作为替代。 “高阶组件”是一个函数的奇特术语,它接受一个React组件类并返回一些行为添加的类。高阶组件可以被视为“装饰器”。你将它们应用于一个组件,他们每个人都会做自己的事情,甚至不需要彼此了解。

这看起来是留下旧语法并推进课程的一个很好的理由。

答案 1 :(得分:3)

createClass语法是创建React组件的原始方法,但似乎已逐步取消class语法和无状态功能组件。

如果您要从createClass class升级组件,则需要注意一些关键差异。

初始状态&amp;默认道具

使用createClass,您可以声明将返回给定组件的初始状态和默认属性的方法。

React.createClass({
  getInitialState() {
    return { foo: 'bar' };
  },
  getDefaultProps() {
    return { baz: 'qux' };
  },
  componentDidMount() {
    console.log(
      this.state, // => { foo: 'bar' }
      this.props  // => { baz: 'qux' }
    );
  }
});

两种语法都已更改。而是在构造函数中分配初始状态。

class extends React.Component {
  constructor() {
    super();
    this.state = { foo: 'bar' };
  }
}

并将默认道具声明为静态属性。

class Qux extends React.Component {}
Qux.defaultProps = { baz: 'qux' };

混入

createClass语法支持一个名为mixins的概念,它允许您提供其他代码来扩充现有的生命周期方法。

const logOnMount = {
  componentWillMount() {
    console.log('Mounted!', new Date());
  }
};

React.createClass({
  mixins: [logOnMount]
});

任何使用logOnMount mixin的组件都会在安装时将时间戳记录到控制台。

不支持使用class语法的mixin,但您可以使用higher-order components来实现相同的功能。

function logOnMount(Component) {
  return function(props) {
    console.log('Mounted!', new Date());
    return (
      <Component {...props} />
    );
  }
}

自动绑定

createClass语法提供了一些方便的自动绑定,因此您可以安全地将组件方法作为回调传递,而不必担心以this的错误上下文结束。

React.createClass({
  bar() {
    return true;
  },
  foo() {
    this.bar();
  },
  render() {
    return <button onClick={this.foo}>Click</button>;
  }
});

onClick处理程序将尝试调用this.foo并将this设置为已触发的事件,但由于this.foo已被自动调整以获得正确的上下文,因此&# 39;没有错误。

这是相同的例子,但是有类。

class extends React.Component {
  bar() {
    return true;
  }
  foo() {
    this.bar(); // Error - undefined is not a function
  }
  render() {
    return <button onClick={this.foo}>Click</button>;
  }
}

foo方法最终将this设置为事件,该事件没有bar属性。

要解决这个问题,您需要在构造函数中显式绑定方法,或者从箭头函数内部调用方法。

constructor() {
  this.foo = this.foo.bind(this);
}

// or

render() {
  return <button onClick={e => this.foo()}>Click</button>;
}

答案 2 :(得分:1)

install.py语法是ES2015中的新语法,您可以在MDN上阅读。

存在class函数,因为ES2015之前的javascript不支持类。

具体的反应存在一些差异,详见the react docs,但就个人而言,如果你能够,我会使用新的类语法。