Как стать автором
Обновить
6
0

Пользователь

Отправить сообщение

Сорвали с языка просто. Сам об этом постоянно говорю. К сожалению, такие процессы по приему людей выстроены не только в Яндекс. Еще посчитайте сколько компании теряют денег на такие сложные собеседования.

Добрый вечер. Спасибо за комментарий. По поводу переезда уже есть статья от моего коллеги Романа
Я работал в большой компании (60к+ человек) и мы переходили с Win XP на Win 7. Вот были времена… Работа по 12 часов, бесконечные тренинги. В общем было весело. А потом еще и на Google Chrome c IE и на Gmail c Outlook. Все это стоит для больших компании Огромных денег. И это для них никак не окупиться. Нужно что бы в топ менеджменте были люди которые понимали, что мир не стоит на месте и людям нужны современные инструменты. Хирург же не будет оперировать ржавым скальпелем. Так и современного работнику нужны новые и хорошие инструменты, что бы эффективно выполнять свою работу. Если руководство компании этого не понимает, то это полностью их просчет.

Нет, конечно. В обычном компоненте вы можете создать функцию внутри него и вызывать ее this.functionName. В случае stateless компонента функцию можно вынести наружу, иначе она будет создаваться каждый раз заново при перерендере компонента.

Это всегда однозначно ясно.

Как показывает практика, к сожалению, не всем. И я очень рад, что мы с вами обсудили данный топик.
Все что влияет на рендер одного компонента в state. Двух и более в props. Остальное в переменные класса. — Для меня это золотое правило которым я руководствуюсь при выборе где мне хранить данные.
Я постараюсь собрать все, о чем мы с вами здесь говорили и уточнить react/no-did-mount-set-state, раз он вызвал столько неоднозначности у читающих.

Не нужны тут никакие зеркала.

Усложним пример. В прочем, мы уже залезли в дебри и крайние случаи. Вам нужно снять размеры с дива, а отрендерить, например, таблицу. Или снять размеры с дива с целью выяснения максимальной высоты строки. Или любых два разных элемента на ваш выбор.


Всё остальное в вашем комментарии у вас, похоже, базируется на том, что у вас есть некий монстр-пожиратель-ресурсов, который рендерит 1000 компонент и трогать его через React себе дороже.

Очень часто люди в componentDidMount меняют данные которые влияют на рендеринг, и делают это, как правило, не в каких то особых случаях, а просто потому, что захотелось. Мой посыл избегать этого и:


You may call setState() immediately in componentDidMount(). It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won’t see the intermediate state. Use this pattern with caution because it often causes performance issues.

То что я и хотел донести:
Use this pattern with caution — используйте с осторожностью, потому что — it often causes performance — это часто влияет на производительность.
https://reactjs.org/docs/react-component.html#componentdidmount

Смотрите. Изначальный посыл был не менять state в componentDidMount, так как его изменения заставят перерендериться компонент и если, например, компонент рендерит в дом 1000 компонентов, то вы сильно замедлите итоговый рендеринг.
Тот вариант который описывал я и который предлагаете вы, вообще из другой оперы. Он не требует сохранения чего бы то ни было в state. Он маленький. Ссылку на компонент вы сохраняете в переменной класса. В componentDidMount вы получаете размер компонента по ссылке. Далее с этой информаций вы можете делать что хотите. Вы можете запросить эти данные из другого компонента, вы можете поменять в итоге state и перерендерить этот маленький компонент. Что угодно. Это будет в итоге не существенно. Но вот если вы таким образом будете рендерить 1000 компонентов и все их потом перерендеривать, это будет уже существенно и разницу вы заметите.
Что то вы отшутились на мои комментарии :) Ну тогда и я могу посмеяться :)
> Накладные расходы на «зеркало» превысят всю возможную мышиную возню на React. React работает с VDom. А зеркало это реальный DOM. Разница в производительности — на порядки.

Вы не сможете получить реальные размеры текста не отрендерив его. Про проблему отображения текста я писал выше.
> Добавьте к этому то, что реальный размер для зеркала вы получите только, зная реальное место, куда его поместить.
В это случае это не нужно. Вы его рендерите считываете размеры и убираете или прячете.
> Самое время переписать его задействовав двойной рендер :) Поймите, операции с DOM, такие как reflow ОЧЕНЬ дорогие
Это все понятно.
> (в вашем случае render VDOM для одного v-тега)
Не получите вы реальный размер текста в VDOM.

Я и не претендую быть истиной в одной инстанции. Я поделился своим мнением и опытом. Ваше право не согласиться и оспорить его. В споре, как говорится, рождается истина.
Вы написали, что моя статья субъективна. Она субъективна и я это не отрицаю. Вы описали ваши замечания в комментарии. Это ваши замечания которые ВЫ считаете правильными. То-есть они субъективны.
К сожаление, у меня нет много свободного времени для описания всех имеющихся проблем в Реакте. Я описал только самые популярные на мой взгляд. Для этих проблем не глупые люди написали даже отдельные правила для eslint (надеюсь, вы не будете отрицать, что если их написали и добавили в eslint, значит они имеют место быть и даже считаются совсем не субъективными проблемами). Если у вас много опыта и есть время, welcome. Я с удовольствием почитаю про ваш опыт и проблемы в статье на хабре.

В вашем примере вам нужно получить ссылку на уже отрендеренный компонент и получить его размеры. Вы сохраняете ссылку на объект в переменной класса, так как эта информация не нужна вам для рендеринга. Далее в componentDidMount вы получаете значения и вызываете ре-рендеринг компонента. В этом случае обходного пути я не вижу, но я пытаюсь донести именно проблему данного подхода. Зачем вам рендерить именно весь компонент? Возможно, можно создать его скрытое зеркало, получить размеры и потом отрендерить сам компонент уже со всем содержимым. В моей практике был всего один раз когда мне понадобилось делать данную бяку: это связано с textarea и текстом в нем. Что бы узнать нужный мне размер textarea для его последующего рендеринга, я отрисовывал его скрытое зеркало в доме, брал размеры, а потом рендерил textarea с текстом. Связано это с тем, что размер текста может быть разным в зависимости от браузера, платформы и так далее. Есть вариант решения данной проблемы используя рендеринг текста в канвасе и считывания его размеров. Вы так же можете написать компонент который будет рендерить текст в канвасе и потом, обращаясь к нему, получать нужные вам размеры. Но описываемый мной пример, скорее, исключения из правила, подтверждающее верность данного правила. Вся реализация этого компонента выглядит как страшный костыль и пугает меня каждый раз когда я вижу его код. Я написал его не потому, что я так захотел, а потому, что порой во фронте случается такая боль.

Спасибо за вашу критику.
> На мой взгляд эта статья полна предрассудков и субъективщины.
собственно как и ваш комментарий :)
Я описал свой личный опыт и те проблемы с которыми столкнулся лично я. Вы, возможно, еще их не видели, а может просто не обратили на них внимание.
> Пожалуйста, уберите оттуда prevState.counter++
Спасибо. Поправил. Действительно проглядел данный кусок кода.
> Скажем зачастую приходится вызывать .setState при получении реальной ссылки на DomElement (к примеру, чтобы узнать размеры объекта).
То что вы описали отлично сохраняется как переменная класса. Я как раз и использую ее частенько для сохранения ссылок на элементы в доме. Если можно избежать второго рендера почему этого не сделать? Преждевременная оптимизация? По-моему просто попытка написать нормальный и производительный код. К сожалению, последнее время фронт-енд разработчики перестали заботиться о производительности и размере бандла заранее. Нужно вначале довести до того что бы предложение безбожно тормозило и размер бандла был за 10 Мб, и только после этого заниматься оптимизацией. Мой вопрос заключается в том, что почему если вы знаете проблему, как опытны разработчик, не исправить ее сразу не доводя до крайности? Еще раз. Это не преждевременная оптимизация, это просто попытка написать чистый и производительный код.
Проблема про которую я говорю в статье описывает ситуацию изменения стейта в целом. Не важно насколько они значительные или нет. Чем они больше тем тормознее будет ваш компонент. Но негативный эффект все равно будет. Не важно, что при изменении всего одной переменной он не значительный, он есть и это факт. При изменении массива в 5к объектов, который вы положили в стейт, вы получите еще больший негативный эффект.
Поменяйте в setState массив строк который вы передаете в рендер компонента и увидете разницу.

Вы просто это условие переносите в инициализацию стейта или конструктор если вам нужны пропсы.
Дублировать как раз ничего и не нужно будет в этом случае.
Если компонент очень тяжелый (например, таблица с 5к строками) и рендериться очень много времени, вы сможете сэкономить 50% времени от начального рендеринга, а это может быть очень не мало.

Это ж в какой вселенной наличие слова чистый подразумевает отсылку к чистым функциям?
Если у меня есть чистая тарелка то что она должна быть детерминирована?

Простите, но не совсем понял при чем здесь чистая тарелка. Я пытаюсь объяснить, что именно я подразумеваю под понятием PureComponent. Это лично мое определение.
И в библиотеке recompose есть HOC который называется pure и делает компонент pure, что как бы наталкивает на мысль, что обычный функциональный компонент не является pure.

Я не использовал библиотеку recompose в продакшене, но читал пару статей про нее. Не понимаю, при чем здесь данная библиотека и мое определение чистого компонента.

Нет. Я имею ввиду:


class MyComponent extends React.Component {
  state = {
    loading: true,
  }

  render() {
    const { loading } = this.state;
    if(loading) {
       return <Loader />;
    }
    //....
}

const — это константа. То есть переменная, которой значение можно присвоить только один раз.
let — это переменная, которой значение можно присвоить несколько раз.
В сети есть очень много бенчмарков которые показывают сравнение производетельности let, const и var.
Так же рекомендую отличную статью от Эрика
Мои личные рекомендации — использовать только const кроме тех редких случаев когда вам действительно нужна мутация данных (поможет в этом let).

Airbnb, в целом, сделала большую работу по агригации полезных eslint правил, но я предпочитаю, более строгие варианты в некоторых местах. Исключительно для улучшения чтения кода и дальнейшего его поддерживания.
Кажется все перечисленные правила есть тут, и детектируемы линтерами.

Все верно, но я ставил своей целью не только дать ссылки на эти правила, но и объяснить почему их необходимо выполнять. Надеюсь у меня получилось.
1

Информация

В рейтинге
Не участвует
Откуда
Москва, Москва и Московская обл., Россия
Зарегистрирован
Активность