- Оригинальный адрес:The constructor is dead, long live the constructor!
- Оригинальный автор:Donavon West
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:unicar
- Корректор:FateZeros, pot-code
Конструкторы мертвы, да здравствуют конструкторы!
Попрощайтесь с банальным конструктором класса в компонентах 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,внешний интерфейс,задняя часть,блокчейн,товар,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.