We want to hear from you!Take our 2021 Community Survey!
This site is no longer updated.Go to react.dev

React без ES6

These docs are old and won’t be updated. Go to react.dev for the new React docs.

Зазвичай, ви б оголосили React-компонент у вигляді JavaScript-класу:

class Greeting extends React.Component {
  render() {
    return <h1>Привіт, {this.props.name}</h1>;
  }
}

Якщо ви досі не використовуєте ES6, ви можете використати пакет create-react-class:

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

API ES6-класів схожий до createReactClass() за деякими виключеннями.

Оголошення властивостей компонента

За допомогою функцій та класів ES6 defaultProps оголошуються як властивість самого компонента:

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

Greeting.defaultProps = {
  name: 'Марія'
};

Використовуючи createReactClass(), вам необхідно визначити метод getDefaultProps() як функцію в переданому об’єкті:

var Greeting = createReactClass({
  getDefaultProps: function() {
    return {
      name: 'Марія'
    };
  },

  // ...

});

Встановлення початкового стану компонента

Використовуючи 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: 'Привіт!'};
    // Цей рядок -- дуже важливий!
    this.handleClick = this.handleClick.bind(this);
  }

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

  render() {
    // Оскільки `this.handleClick` є прив'язаним у конструкторі екземпляра, то ми можемо його використати як обробник події.
    return (
      <button onClick={this.handleClick}>
        Скажи "привіт"
      </button>
    );
  }
}

З використанням createReactClass() це необов’язково, оскільки цей метод прив’язує всі методи до екземпляра компонента:

var SayHello = createReactClass({
  getInitialState: function() {
    return {message: 'Привіт!'};
  },

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

  render: function() {
    return (
      <button onClick={this.handleClick}>
        Скажи "привіт"
      </button>
    );
  }
});

Це означає, що ES6-класи пишуться із трохи більш універсальним кодом для обробників подій, але при цьому продуктивність величезних додатків є трохи вищою.

Якщо універсальний код для вас не занадто привабливий, ви можете увімкнути експериментальну пропозицію синтаксису Class Properties з Babel:

class SayHello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Привіт!'};
  }
  // Тут стрілкова функція виконує прив'язку:
  handleClick = () => {
    alert(this.state.message);
  };

  render() {
    return (
      <button onClick={this.handleClick}>
        Скажи "привіт"
      </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], // Використовуємо міксин
  getInitialState: function() {
    return {seconds: 0};
  },
  componentDidMount: function() {
    this.setInterval(this.tick, 1000); // Викликаємо метод на міксині
  },
  tick: function() {
    this.setState({seconds: this.state.seconds + 1});
  },
  render: function() {
    return (
      <p>
        React працював {this.state.seconds} секунд.
      </p>
    );
  }
});

const root = ReactDOM.createRoot(document.getElementById('example'));
root.render(<TickTock />);

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