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

Комментарии 20

В первом примере код из 8-го

Поправили, спасибо!

В кейсе 6 проблема приведенного кода в том, что он НЕ будет распознан как JSX и соответственно не пройдет транспиляцию, превращающую выражение в return в то, что мы на самом деле хотим. А не то, что там в пояснениях написано. Ну и конечно не надо в общих случаях приводить число к boolean, потому что 0 == false.

Да, пардон, соль все же просто в JS, логические операторы && и || всегда возвращают один из операндов, а не true/false. И в приведенном примере — не тот, который ожидают, и не того типа, на который рассчитывают. Реакт не будет рендерить null, undefined, и false, а всё остальное — как минимум попытается.

Довольно распространённый бедпрактис - производное значение в виде useState+useEffect вместо useMemo или просто вычисления. То есть когда какой-то стейт зависит только от некоторых стейтов/пропов/контекстов и может быть синхронно из них посчитан, и при их изменении подправляется через useEffect. Лишний рендер, да и вообще криво.

Кроме того, самый первый рендер не выполняет useEffect, поэтому все шансы получить "моргание". При useMemo первый рендер сразу вычисляет начальное значение, поэтому если зависимости не меняются по какой-то причине сразу же, то второй рендер не моргает.

Но ещё больше бесит, когда useState+useEffect или useMemo используют для вычисления чего-то тривиального, например:

const isFormValid: boolean = useMemo(
  () => isNameFieldValid && isPasswordFieldValid && isEveryOtherFieldValid,
  [isNameFieldValid, isPasswordFieldValid, isEveryOtherFieldValid]
);

Ну ничего же не сэкономите на вызове хука! Хук будет дольше проверять, изменились ли зависимости, чем если то же самое просто посчитать в лоб:

const isFormValid: boolean = isNameFieldValid && isPasswordFieldValid && isEveryOtherFieldValid;

Можете подробнее расписать пример плохого решения и правильного? Какой-то минимальный пример, потому что я часто использую избыточные useState и useEffect, и не совсем понятно как это упростить

Обезжиренный пример:

const [derivedState, setDerivedState] = useState(...);
useEffect(() => {
  setDerivedState(someFunc(statesOrProps));
}, [statesOrProps...]);

При условии, что setDerivedState не вызывается где-то ещё (например, в событиях). То есть реально зависит только от других стейтов/пропсов/контекстов.

Код выше рекомендуется заменить на:

const derivedState = useMemo(
  () => someFunc(statesOrProps),
  [statesOrProps...]
)

или просто

const derivedState = someFunc(statesOrProps);

в зависимости от того, нужен useMemo или нет.

Не упомянута очень большая ошибка при использовании React, которую совершает автор оригинальной статьи: не использует TypeScript!

Заблуждение, что props вызывают rerender в react. Об этом непосредственно в документации сказано.

Поясните, пожалуйста что вы имеете в виду?

Re-render происходит по 4 триггерам:

  • Изменение свойства в context, на который подписаны

  • Обновление state

  • re-render компонента предка

  • Так же на это могут влиять хуки

Есть кейс, например, когда re-render не будет, хоть prop изменился. Обновление значения в useRef

Спасибо, похоже, тут вопрос в терминологии того, что вы имеете в виду под перерисовкой (re-render).

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

Или такой пример, где в родительском меняется prop и значение в дочернем тоже меняется, однако, опять же, это те же самые DOM-узлы

Разве слушатели (5 ошибка) не лучше через onClick весить? Мб тут бы fetch и его abort подошёл бы больше

Однозначно лучше просто заюзать onClick в том случае. И даже если б вы вещали что-то на dom (например потому что оборачиваете leaflet или аналогичную библиотеку) больше смысла взять useLayout effect. И использовать ref, а не id.

Но у автора вообще есть ряд очень странных советов:

1) деструктурировать прописы и использовать prop types. Деструктуризация — вкусовщина, мы ее делаем но это ни на что не влияет. PropTypes — слабый runtime аналог typescript.

2) выносить тернарник в геттер функцию или 2 компонента которые принимают условия. Геттер на уровне реакта всегда будет перевычисляться, компонент — нет. А решить эту проблему можно намного чище сунув каждую ветку тернарника в отдельный компонент и мб заранее им пропсы заготовив если вам реально не удобно читать 2 строки.

А, ну если он знает, где я живу, то придёт и спросит, почему я так написала, а я объясню. Удобно ?

А есть ли смысл использовать PropTypes, когда используется TypeScript? По мне так это лишний оверхед.

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

Теперь стало понятно, почему наши продукты отстают от иностранных конкурентов.
В книжечках ИНОСТРАННЫХ авторов ведь написано: Писать нужно красиво
В то время как сами иностранные компании просто пишут и создают продукты, а их конкуренты пускай дальше уделяют внимание чистоте кода, табуляции, и т.д и т.п. Ведь в книжечках так написано

Зарегистрируйтесь на Хабре, чтобы оставить комментарий