Если вы разработчик React среднего уровня и хотите стать продвинутым разработчиком React, этот пост для вас!
Рассмотрим наиболее распространенные ошибки, которые вы совершаете.
Каждый заголовок в этом разделе — это вредная привычка, которой вам следует избегать!
Будем использовать классический пример приложения со списком дел, чтобы проиллюстрировать некоторые из своих тезисов.
Для каждой части состояния должен быть один источник правды. Если одна и та же часть информации хранится в состоянии дважды, эти две части состояния могут не синхронизироваться. Вы можете попробовать написать код, синхронизирующий две части состояния, но это не решение, а скорая помощь, связанная с ошибками.
Вот пример повторяющегося состояния в контексте нашего приложения со списком дел. Нам нужно отслеживать элементы в списке дел, а также те, которые были отмечены. Вы можете хранить два массива в состоянии, один из которых содержит все задачи, а другой — только завершенные:
1 2 3 4 5 |
const [todos, setTodos] = useState<Todo[]>([]) const [completedTodos, setCompletedTodos] = useState<Todo[]>([]) |
Но этот код в худшем случае содержит ошибки. Завершенные задачи сохраняются в состоянии дважды, поэтому, если пользователь редактирует текстовое содержимое задачи, а вы только звоните setTodos
, completedTodos
теперь содержит старый текст, который неверен!
Есть несколько способов дедупликации вашего состояния. В этом надуманном примере вы можете просто добавить completed
логическое значение к Todo
типу, чтобы completedTodos
массив больше не был нужен.
В React есть два встроенных способа хранения состояния: useState
и useReducer
. Существует также бесчисленное множество библиотек для управления глобальным состоянием, наиболее популярной из которых является Redux. Поскольку Redux обрабатывает все обновления состояния через редукторы, будем использовать термин «редьюсер» для обозначения как useReducer
редукторов, так и редукторов Redux.
useState
совершенно нормально, когда обновления состояния просты. Например, вы можете useState
отслеживать, установлен ли флажок, или отслеживать value
ввод текста.
При этом, когда обновления состояния становятся даже немного сложными, вы должны использовать редюсер. В частности, вы должны использовать редьюсер каждый раз, когда вы сохраняете массив в состоянии, и пользователь может редактировать каждый элемент в массиве. В контексте нашего приложения списка дел вам определенно следует управлять массивом дел с помощью редьюсера, будь то через useReducer
или Redux.
Редукторы выгодны, потому что:
setState
– еще один способ предотвратить это.dispatch
имеют стабильную идентичность.useState
, но не думаем, что многие люди на самом деле так делают.Разработчики — занятые люди, и написание автоматизированных тестов может занять много времени. Решая, следует ли вам написать тест, спросите себя: «Будет ли этот тест достаточно эффективным, чтобы оправдать время, которое я потратил на его написание?» Если ответ положительный, напишите тест!
Часто разработчики React среднего уровня обычно не пишут тесты, даже если написание теста занимает 5 минут и оказывает среднее или сильное влияние! Такие ситуации мы называем «низко висящими плодами» тестирования. Испытайте низко висящие плоды!!!
На практике это означает написание модульных тестов для всех «автономных» функций, содержащих нетривиальную логику. Под автономными подразумевается чистые функции, которые определены вне компонента React.
Редукторы — прекрасный тому пример! Любые сложные редукторы в вашей кодовой базе должны иметь почти 100% тестовое покрытие. Мы настоятельно рекомендуем разрабатывать сложные редукторы с помощью Test-Driven Development. Это означает, что вы напишете по крайней мере один тест для каждого действия, обрабатываемого редуктором, и чередуете написание теста и написание логики редуктора, которая обеспечивает прохождение теста.
React.memo
, useMemo
, иuseCallback
Пользовательские интерфейсы, основанные на React, могут во многих случаях зависать, особенно когда вы сочетаете частые обновления состояния с компонентами, которые требуют больших затрат для рендеринга (React Select и FontAwesome, я смотрю на вас). React DevTools отлично подходят для выявления проблем с производительностью рендеринга. либо с помощью флажка «Выделять обновления при визуализации компонентов», либо на вкладке профилировщика.
Ваше самое мощное оружие в борьбе с плохой производительностью рендеринга — это рендеринг компонента React.memo
, только если его свойства изменились. Задача здесь заключается в том, чтобы пропсы не менялись при каждом рендеринге, и в этом случае React.memo
они ничего не сделают. Вам нужно будет использовать хуки useMemo
и useCallback
, чтобы предотвратить это.
Активное использование React.memo
, useMemo
и useCallback
для предотвращения проблем с производительностью до того, как они возникнут, но реактивный подход — т.е. ожидание оптимизации до выявления проблемы с производительностью — тоже может сработать.
useEffect
s, которые запускаются слишком часто или недостаточно частоЕдинственная жалоба на React Hooks заключается в том, что ими useEffect
легко злоупотреблять. Чтобы стать продвинутым разработчиком React, вам необходимо полностью понимать поведение useEffect
и массивы зависимостей.
Если вы не используете плагин React Hooks ESLint , вы можете легко пропустить зависимость вашего эффекта, что приведет к тому, что эффект будет выполняться не так часто, как должен. Это легко исправить — просто используйте плагин ESLint и исправьте предупреждения.
Когда у вас есть все зависимости, перечисленные в массиве зависимостей, вы можете обнаружить, что ваш эффект запускается слишком часто. Например, эффект может запускаться при каждом рендеринге и вызывать бесконечный цикл обновления. Не существует универсального решения этой проблемы, поэтому вам нужно проанализировать вашу конкретную ситуацию, чтобы выяснить, что не так. Если ваш эффект зависит от функции, сохранение этой функции в ссылке является полезным шаблоном. Взгляните на пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const funcRef = useRef(func) useEffect(() => { funcRef.current = func }) useEffect(() => { // do some stuff and then call funcRef.current() }, [/* ... */]) |
Как фронтенд-разработчик, вы должны стремиться быть больше, чем просто программистом. Лучшие разработчики интерфейса также являются экспертами в области юзабилити и веб-дизайна, даже если это не отражено в их должностях.
Простота использования означает простоту использования приложения. Например, насколько легко добавить новую задачу в список?
Если у вас есть возможность провести юзабилити-тестирование с реальными пользователями, это здорово. У большинства из нас нет такой роскоши, поэтому мы должны разрабатывать интерфейсы, основываясь на нашей интуиции относительно того, что удобно для пользователя. Во многом это сводится к здравому смыслу и наблюдению за тем, что работает или не работает в приложениях, которые вы используете каждый день.
Вот несколько простых рекомендаций по удобству использования, которые вы можете реализовать уже сегодня:
cursor: pointer
в CSS. Наведите указатель мыши на кнопку Bootstrap, чтобы увидеть эти рекомендации в действии.Если вы хотите эффективно создавать красивые пользовательские интерфейсы, вы должны освоить CSS и веб-дизайн. Мы не ожидаем, что разработчики среднего уровня сразу же смогут создавать чистые и удобные интерфейсы, сохраняя при этом высокую эффективность. Требуется время, чтобы изучить тонкости CSS и развить интуицию в отношении того, что выглядит хорошо. Но вы должны работать над этим и становиться лучше с течением времени!
Трудно дать конкретные советы по улучшению ваших навыков стилизации, но вот один: освойте flexbox. Хотя поначалу flexbox может показаться пугающим, это универсальный и мощный инструмент, который вы можете использовать для создания практически всех макетов, которые вам понадобятся в повседневной разработке.
Это покрывает вредные привычки! Посмотрите, виноваты ли вы в чем-либо из этого, и работайте над улучшением. Теперь уменьшим масштаб и обсудим некоторые лучшие практики, которые могут улучшить ваши кодовые базы React.
Обычный JavaScript — хороший язык, но отсутствие проверки типов делает его плохим выбором для чего угодно, кроме небольших хобби-проектов. Написание всего вашего кода на TypeScript значительно повысит стабильность и ремонтопригодность вашего приложения.
Если TypeScript кажется вам слишком сложным, продолжайте работать над ним. Как только вы освоите язык, вы сможете писать на TypeScript так же быстро, как сейчас на JavaScript.
Как уже говорилось в разделе «Плохие привычки» этого поста, useEffect
правильно написать s сложно. Это особенно верно, когда вы используете useEffect
прямую загрузку данных из API вашего бэкэнда. Вы избавите себя от бесчисленных головных болей, используя библиотеку, которая абстрагирует детали выборки данных. Моим личным предпочтением является React Query , хотя RTK Query , SWR и Apollo также являются отличными вариантами.
Рендеринг на стороне сервера (SSR) — одна из самых крутых функций React. Это также значительно усложняет ваше приложение. Хотя такие фреймворки, как Next.js, значительно упрощают SSR, все же существует неизбежная сложность, с которой необходимо иметь дело. Если вам нужен SSR для SEO или быстрой загрузки на мобильных устройствах, обязательно используйте его. Но если вы пишете бизнес-приложение, не имеющее этих требований, просто используйте рендеринг на стороне клиента. Вы поблагодаришь нас за это позже.
CSS приложения может быстро превратиться в беспорядок, который никто не понимает. Sass и другие препроцессоры CSS добавляют несколько приятных мелочей, но по-прежнему в значительной степени страдают от тех же проблем, что и ванильный CSS.
Считаем, что стили должны быть привязаны к отдельным компонентам React, а CSS должен быть совмещен с кодом React. Настоятельно рекомендую прочитать отличный пост в блоге Кента С. Доддса о преимуществах совместного размещения. Привязка CSS к отдельным компонентам приводит к повторному использованию компонентов в качестве основного метода совместного использования стилей и предотвращает проблемы, когда стили случайно применяются к неправильным элементам.
Вы можете реализовать совмещенные стили на уровне компонентов с помощью Emotion, styled-components или CSS Modules среди других подобных библиотек. Наши предпочтения Emotion с css
реквизитом.
Статья очень полезна, для тех, кто хочет идти свой путь разработчик кропотливо, но правильно!
Источник статьи: http://dev.to/