[Перевод] Конструкторы мертвы, да здравствует конструктор!

Программа перевода самородков React.js Babel

Конструкторы мертвы, да здравствуют конструкторы!

Попрощайтесь с банальным конструктором класса в компонентах React

Photo by Samuel Zeller on Unsplash

В то время как функциональные компоненты без сохранения состояния (SFC) являются отличным оружием, компоненты, подобные ES6, по-прежнему используются по умолчанию для создания компонентов React, а также их состояний и жизненных циклов.

Предположим, в следующем примере показан компонент класса ES6 (показана только упрощенная часть кода).

class Foo extends Component {
  constructor(props) {
    super(props); 
    this.state = { loading: true };
  }
  async componentDidMount() {
    const data = await loadStuff();
    this.setState({ loading: false, data });
  }
  render() {
    const { loading, data } = this.state;
    return (
      {loading ? <Loading /> : <View {...data} />}
    );
  }
}

существуетconstructorинициализирован вstate, и дальшеcomponentDidMountзагружать данные асинхронно вloadingсостояние для рендерингаViewэтот компонент. Для меня это довольно стандартный шаблон, если вы знакомы с моим предыдущим стилем кодирования.

атрибут класса

мы все знаемconstructorЗдесь мы инициализируем свойства экземпляра, как в этом случаеstateТакой же. Если вы уверенно говорите себе: «Точно! ', тогда вы правы... но для предстоящего предложения свойства класса ES.nextclass properties proposalЭто не так, поскольку предложение в настоящее время находится на третьем этапе.

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

class Foo extends Component {
  state = { loading: true };
  ...
}

Babel транспилирует ваш код в фоновом режиме и добавит предыдущийconstructor. Ниже приведен результат транспиляции вашего фрагмента кода Babel.

Обратите внимание, что здесь Babel фактически проходит все параметрыsuper- не толькоprops. это также будетsuperВозвращаемое значение передается обратно вызывающей стороне. Хотя эти двое чувствуют себя немного излишними, им это действительно нужно.

Конструктор все еще там, просто вы его не видите.

метод привязки

использоватьconstructorДругая причина заключается в том, чтобы привязать функцию кthis,Следующим образом.

class Foo extends Component {
  constructor(props) {
    super(props); 
    this.myHandler = this.myHandler.bind(this);
  }
  myHandler() {
    // some code here that references this
  }
  ...
}

Но некоторые люди полностью избегают этой проблемы, присваивая выражение функции непосредственно свойству класса, но это уже другая история. Чтобы узнать больше, ознакомьтесь с другими моими статьями React на основе классов ES6.Demystifying Memory Usage using ES6 React Classes.

Demystifying Memory Usage using ES6 React Classes

Итак, давайте предположим, что вы принадлежитеbindЛагерь (даже если нет, наберитесь терпения и прочитайте). нам все еще нужноconstructorПривязка, да? Не обязательно. Здесь мы можем использовать тот же подход, что и выше, для атрибутов класса.

class Foo extends Component {
  myHandler = this.myHandler.bind(this);
  myHandler() {
    // some code here that references this
  }
  ...
}

Инициализировать состояние с реквизитами

тогда, если вам нужноpropsпроизводное от начальногоstate, скажем, инициализировать значение по умолчанию? Тогда вы всегда должны использоватьconstructorправильно?

class Foo extends Component {
  constructor(props) {
    super(props); 
    this.state = {
      color: this.props.initialColor
    };
  }
  render() {
    const { color } = this.state;
    return (
      <div>
       {color}
      </div>
    );
  }
}

Не о! Атрибуты класса снова спасают жизни! мы можем получитьthisа такжеprops.

class Foo extends Component {
  state = {
    color: this.props.initialColor
  };
  ...
}

получить данные

тогда, может быть, нам нужноconstructorвосстановить данные? В принципе не надо. Как мы видели в первом примере кода, загрузка любых данных должна бытьcomponentDidMountзавершенный. Но зачем быть одномуcomponentDidMountШерстяная ткань? Поскольку это гарантирует, что выборка данных не будет выполняться, когда компонент работает на стороне сервера — то же самое верно для рендеринга на стороне сервера (SSR)  — , потому чтоcomponentDidMountне будет выполняться на стороне сервера.

В заключение

Из вышеизложенного видно, что нам больше не нуженconstructor(или любое другое свойство экземпляра), чтобы установить начальноеstate. Нам также не нужны конструкторы для привязки функций кthis, и изpropsустановить начальнуюstate. При этом нам не нужноconstructorПолучить данные внутри.

Так почему же нам все еще нужно использовать конструкторы в компонентах React?

как сказать... тебе это действительно не нужно

Однако, если у вас есть какой-то неоднозначный вариант использования, когда вам нужно инициализировать что-то в компоненте как с клиента, так и с сервера, конструкторы по-прежнему являются хорошим способом. у вас также естьcomponentWillMountЭту функцию ловушки можно использовать. С точки зрения внутреннего механизма React вызовет эту функцию ловушки сразу после создания класса как на стороне клиента, так и на стороне сервера (то есть вызов конструктора).

Итак, что касается компонентов React, я твердо убежден в следующем: конструкторы мертвы, да здравствуют конструкторы!


I also write for the American Express Engineering Blog. Check out my other works and the works of my talented co-workers at AmericanExpress.io. You can also follow me on Twitter.


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,товар,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.