React 20 - 不使用ES6(React Without ES6)

栏目: JavaScript · 发布时间: 6年前

内容简介:React 20 - 不使用ES6(React Without ES6)

原文

Normally you would define a React component as a plain JavaScript class:

通常情况下,定义一个React组件和定义一个普通JavaScript类相似:

class Greeting extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

If you don’t use ES6 yet, you may use the create-react-class module instead:

如果不适用ES6语法,也可以使用 create-react-class 模块替代:

var createReactClass = require('create-react-class');
var Greeting = createReactClass({
  render: function() {
    return <h1>Hello, {this.props.name}</h1>;
  }
});

The API of ES6 classes is similar to createReactClass() with a few exceptions.

除个别情况外, createReactClass() 的API和ES6的类形式基本一致。

声明默认属性(Declaring Default Props)

With functions and ES6 classes defaultProps is defined as a property on the component itself:

在函数形式和ES6类形式中, defaultProps 直接定义在组件上:

class Greeting extends React.Component {
  // ...
}

Greeting.defaultProps = {
  name: 'Mary'
};

With createReactClass() , you need to define getDefaultProps() as a function on the passed object:

createReactClass() 中,需要在传入的配置对象中定义 getDefaultProps() 方法:

var Greeting = createReactClass({
  getDefaultProps: function() {
    return {
      name: 'Mary'
    };
  },

  // ...

});

设置初始状态(Setting the Initial State)

In ES6 classes, you can define the initial state by assigning this.state in the constructor:

在ES6类形式中,直接在构造函数中为 this.state 属性赋值初始状态即可:

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
  }
  // ...
}

With createReactClass() , you have to provide a separate getInitialState method that returns the initial state:

createReactClass() 中,必须提供一个单独的 getInitialState 方法来返回初始状态:

var Counter = createReactClass({
  getInitialState: function() {
    return {count: this.props.initialCount};
  },
  // ...
});

自动绑定(Autobinding)

In React components declared as ES6 classes, methods follow the same semantics as regular ES6 classes. This means that they don’t automatically bind this to the instance. You’ll have to explicitly use .bind(this) in the constructor:

在ES6类形式的React组件中,方法的语义和正规的ES6类方法相同。这意味着不会不会自动将 this 绑定到实例方法上。必须在构造函数中显式的使用 .bind(this) 方法:

class SayHello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Hello!'};
    // This line is important!
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    alert(this.state.message);
  }

  render() {
    // Because `this.handleClick` is bound, we can use it as an event handler.
    return (
      <button onClick={this.handleClick}>
        Say hello
      </button>
    );
  }
}

With createReactClass() , this is not necessary because it binds all methods:

createReactClass() 中,会自动绑定所有方法:

var SayHello = createReactClass({
  getInitialState: function() {
    return {message: 'Hello!'};
  },

  handleClick: function() {
    alert(this.state.message);
  },

  render: function() {
    return (
      <button onClick={this.handleClick}>
        Say hello
      </button>
    );
  }
});

This means writing ES6 classes comes with a little more boilerplate code for event handlers, but the upside is slightly better performance in large applications.

有可能会感觉ES6类形式的事件处理器中会存在些许的模板代码,但在大型应用中这会带来更好的性能。

If the boilerplate code is too unattractive to you, you may enable the experimental Class Properties syntax proposal with Babel:

如果不能接受这样的模板代码,可以借住Babel启用 类属性 试验 语法:

class SayHello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Hello!'};
  }
  // WARNING: this syntax is experimental!
  // Using an arrow here binds the method:
  handleClick = () => {
    alert(this.state.message);
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Say hello
      </button>
    );
  }
}

Please note that the syntax above is experimental and the syntax may change, or the proposal might not make it into the language.

请注意上面的语法是 试验 阶段,未来可能会发生更改,也可能会从规范中剔除。

If you’d rather play it safe, you have a few options:

  • Bind methods in the constructor.
  • Use arrow functions, e.g. onClick={(e) => this.handleClick(e)} .
  • Keep using createReactClass .

如果期待更安全,可以使用下面的方式:

  • 在构造函数中显式绑定。
  • 使用剪头函数,比如 onClick={(e) => this.handleClick(e)}
  • 继续使用 createReactClass

混合(Mixins)

提醒(Note):

ES6 launched without any mixin support. Therefore, there is no support for mixins when you use React with ES6 classes.

ES6不提供Mixin的支持。就是说,当时用ES6类形式的时候不能使用任何Mixin。

We also found numerous issues in codebases using mixins, and don’t recommend using them in the new code .

我们发现在代码中使用Mixin会带来许多问题, 所以不建议在新代码中继续使用

This section exists only for the reference.

写这一小节只是为了供参考而已。

Sometimes very different components may share some common functionality. These are sometimes called cross-cutting concerns . createReactClass lets you use a legacy mixins system for that.

有时候,完全不同的组件之间会存在一些通用功能,这种情况被称作 横切关注点 createReactClass 提供了 mixins 功能来解决这个问题。

One common use case is a component wanting to update itself on a time interval. It’s easy to use setInterval() , but it’s important to cancel your interval when you don’t need it anymore to save memory. React provides lifecycle methods that let you know when a component is about to be created or destroyed. Let’s create a simple mixin that uses these methods to provide an easy setInterval() function that will automatically get cleaned up when your component is destroyed.

一个常见的情况是,比如组件中需要定时更新。可以简单通过 setInterval() 方法来实现,但重要的是在不需要使用它的时候将其销毁以释放内存。React提供了 生命周期方法 以监听组件的创建和销毁。下面使用mixin来实现组件销毁时自动将 setInterval() 方法销毁。

var SetIntervalMixin = {
  componentWillMount: function() {
    this.intervals = [];
  },
  setInterval: function() {
    this.intervals.push(setInterval.apply(null, arguments));
  },
  componentWillUnmount: function() {
    this.intervals.forEach(clearInterval);
  }
};

var createReactClass = require('create-react-class');

var TickTock = createReactClass({
  mixins: [SetIntervalMixin], // Use the mixin
  getInitialState: function() {
    return {seconds: 0};
  },
  componentDidMount: function() {
    this.setInterval(this.tick, 1000); // Call a method on the mixin
  },
  tick: function() {
    this.setState({seconds: this.state.seconds + 1});
  },
  render: function() {
    return (
      <p>
        React has been running for {this.state.seconds} seconds.
      </p>
    );
  }
});

ReactDOM.render(
  <TickTock />,
  document.getElementById('example')
);

If a component is using multiple mixins and several mixins define the same lifecycle method (i.e. several mixins want to do some cleanup when the component is destroyed), all of the lifecycle methods are guaranteed to be called. Methods defined on mixins run in the order mixins were listed, followed by a method call on the component.

如果在一个组件中使用了多个Mixin并且有些Mixin定义了相同的生命周期方法(比如,几个Mixin都需要在组件销毁的时候做清理工作),所有的生命周期方法都会保证被调用到,组件会按照Mixin在组件中的定义顺序依次调用。


以上所述就是小编给大家介绍的《React 20 - 不使用ES6(React Without ES6)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

新零售进化论

新零售进化论

陈欢、陈澄波 / 中信出版社 / 2018-7 / 49.00

本书主要介绍了新零售的进化现象和规律,提出了新零售的第一性原理是物理数据二重性,即在新零售时代,所有的人、货、场既是物理的也是数据的。 通过这个原点,进一步衍生出了新零售的八大核心算法,并用大量的辅助观点和新零售案例来揭示新零售背后的算法逻辑。 综合一系列的理论推演和案例讲解,作者重点回答了以下3个问题: ● 我们是行业的强者,如果跟不上新零售的潮流,会不会被淘汰? ● 我......一起来看看 《新零售进化论》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具