jobn123 / blog

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

11. react on es6+

jobn123 opened this issue · comments

commented

最近React可是火的不行,正好最近刚看过ES6,想结合React写几个demo也好熟悉熟悉。但是react写法还都是es5,然后在Babel的blog找到一篇文章,本文就是翻译自这篇文章,原文地址:http://babeljs.io/blog/2015/06/07/react-on-es6-plus/

Classes

目前为止最明显的变化是当我们选择用class definition syntax(类声明语法)时,如何用ES6+React组件。我们可以用ES6 的class声明一个变量继承于React.Component的方式代替用React.createClass

  render() {
    return <img alt={this.props.caption} src={this.props.src} />;
  }
}

立刻你就会注意到微妙的变化,当声明类的时候,我们可以用更简洁的语法。

// The ES5 way
var Photo = React.createClass({
  handleDoubleTap: function(e) { … },
  render: function() { … },
});
// The ES6+ way
class Photo extends React.Component {
  handleDoubleTap(e) { … }
  render() { … }
}

用class的时候constructor 代替 componentWillMount

// The ES5 way
var EmbedModal = React.createClass({
  componentWillMount: function() { … },
});
// The ES6+ way
class EmbedModal extends React.Component {
  constructor(props) {
    super(props);
    // Operations usually carried out in componentWillMount go here
  }
}

Property initializers

// The ES5 way
var Video = React.createClass({
  getDefaultProps: function() {
    return {
      autoPlay: false,
      maxLoops: 10,
    };
  },
  getInitialState: function() {
    return {
      loopsRemaining: this.props.maxLoops,
    };
  },
  propTypes: {
    autoPlay: React.PropTypes.bool.isRequired,
    maxLoops: React.PropTypes.number.isRequired,
    posterFrameSrc: React.PropTypes.string.isRequired,
    videoSrc: React.PropTypes.string.isRequired,
  },
});
// The ES6+ way
class Video extends React.Component {
  static defaultProps = {
    autoPlay: false,
    maxLoops: 10,
  }
  static propTypes = {
    autoPlay: React.PropTypes.bool.isRequired,
    maxLoops: React.PropTypes.number.isRequired,
    posterFrameSrc: React.PropTypes.string.isRequired,
    videoSrc: React.PropTypes.string.isRequired,
  }
  state = {
    loopsRemaining: this.props.maxLoops,
  }
}

Arrow functions

// Autobinding, brought to you by React.createClass
var PostInfo = React.createClass({
  handleOptionsButtonClick: function(e) {
    // Here, 'this' refers to the component instance.
    this.setState({showOptionsModal: true});
  },
});
// Manually bind, wherever you need to
class PostInfo extends React.Component {
  constructor(props) {
    super(props);
    // Manually bind this method to the component instance...
    this.handleOptionsButtonClick = this.handleOptionsButtonClick.bind(this);
  }
  handleOptionsButtonClick(e) {
    // ...to ensure that 'this' refers to the component instance here.
    this.setState({showOptionsModal: true});
  }
}
class PostInfo extends React.Component {
  handleOptionsButtonClick = (e) => {
    this.setState({showOptionsModal: true});
  }
}

ES6的箭头函数共享一个相同的this对象

Dynamic property names & template strings

//ES5
var Form = React.createClass({
  onChange: function(inputName, e) {
    var stateToSet = {};
    stateToSet[inputName + 'Value'] = e.target.value;
    this.setState(stateToSet);
  },
});
//ES6
class Form extends React.Component {
  onChange(inputName, e) {
    this.setState({
      [`${inputName}Value`]: e.target.value,
    });
  }
}

Destructuring & spread attributes

class AutoloadingPostsGrid extends React.Component {
  render() {
    var {
      className,
      ...others,  // contains all properties of this.props except for className
    } = this.props;
    return (
      <div className={className}>
        <PostsGrid {...others} />
        <button onClick={this.handleLoadMoreClick}>Load more</button>
      </div>
    );
  }
}

下面的代码尽管this.props存在一个className,元素将得到className “override”

    <div {...this.props} className="override">
    ...
    </div>

下面的写法元素将会有一个className “base” 除非 this.props存在一个className对其重写

div className="base" {...this.props}>
  …
</div>