Spec-Zone.ru › React 17

React без ES6

Обычно вы определяете компонент React как обычный JavaScript-класс:

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

Если вы еще не используете ES6, вы можете использовать модуль create-react-class вместо него:

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

API классов ES6 похож на createReactClass(), за исключением нескольких моментов.

Определение свойств по умолчанию

С функциями и классами ES6 defaultProps определяются как свойства самого компонента:

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

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

С createReactClass(), вам нужно определить getDefaultProps() как функцию в переданном объекте:

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

  // ...

});

Установка начального состояния

В классах ES6 вы можете определить начальное состояние, назначив this.state в конструкторе:

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

С createReactClass(), вам нужно предоставить отдельный метод getInitialState, который возвращает начальное состояние:

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

Автосвязывание

В компонентах React, объявленных как классы ES6, методы следуют тем же семантикам, что и обычные классы 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>
    );
  }
}

С 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>
    );
  }
});

Это означает, что написание классов ES6 влечёт за собой немного больше кода для обработчиков событий, но преимущество заключается в немного лучшей производительности в больших приложениях.

Если код с ненужными фрагментами выглядит не привлекательно, вы можете включить экспериментальную синтаксическую конструкцию свойств классов с 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>
    );
  }
}

Обратите внимание, что приведенный выше синтаксис является экспериментальным и может измениться, или предложение может не войти в язык.

Если вы хотите быть на безопасной стороне, у вас есть несколько вариантов:

  • Связать методы в конструкторе.
  • Использовать стрелочные функции, например, onClick={(e) => this.handleClick(e)}.
  • Продолжать использовать createReactClass.

Миксины

Примечание:

ES6 был выпущен без поддержки миксинов. Поэтому нет поддержки миксинов при использовании React с классами ES6.

Мы также обнаружили много проблем в кодовой базе, использующей миксины, и не рекомендуем использовать их в новом коде.

Этот раздел существует только для справки.

Иногда очень разные компоненты могут разделять некоторую общую функциональность. Это иногда называют влияющими на всё аспектами. createReactClass позволяет использовать устаревшую систему mixins для этого.

Один из распространённых случаев использования — это компонент, который хочет обновлять себя с интервалом времени. Его легко использовать с setInterval(), но важно отменять ваш интервал, когда вам он больше не нужен, чтобы сохранить память. React предоставляет методы жизненного цикла, которые сообщают вам, когда компонент собирается быть создан или уничтожен. Давайте создадим простой миксин, который использует эти методы, чтобы предоставить лёгкую функцию 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')
);

Если компонент использует несколько миксинов и несколько миксинов определяют один и тот же метод жизненного цикла (например, несколько миксинов хотят выполнить некоторую очистку при уничтожении компонента), все методы жизненного цикла гарантированно будут вызваны. Методы, определённые в миксинах, выполняются в порядке, в котором миксины были перечислены, за которым следует вызов метода компонента.

Полезная ли эта страница?

© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://17.reactjs.org/docs/react-without-es6.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API