Show your code Saturday: код-рев’ю #14

Усі статті, обговорення, новини про Front-end — в одному місці. Підписуйтеся на телеграм-канал!

Коментар редакції. Show your code Saturday — це інтерактивна рубрика, у якій кожен охочий може поділитися власним проєктом, написавши про нього в коментарях. А ми натомість щосуботи обираємо найцікавіший і розповідатимемо детальніше.

Сьогодні ми хочемо поділитися з вами роботою користувачи Illia Hloza.


Наш активний учасник спільноти Максим Рудний зробив код-рев’ю проєкту! Тож далі передаємо слово Максиму 👇

Дисклеймер: я не є автором коду і не знаю причин реалізації будь-якої частини коду таким чином, як це є. Стиль написання коду без ознайомлення з Code Style та Code Convention проєкту не можу критикувати, може це так було задумано.

Сьогоднішній проєкт мене здивував. За всі роки роботи з React я не бачив такого коду та рішення. Особливо на цей огляд я хочу почути аргументацію автора. Чому були прийняті ті чи інші рішення? Який аналіз він проводив? Я гадаю, він зможе прояснити хід своїх думок, адже його позиція Senior Frontend-розробник.

Розбір буде жорстким, адже код написаний не початківцем (навіть з урахуванням, що коду близько року). Що ж, подивімось що можна покращити в коді.

Повний розбір з усім зауваженнями, як завжди у відео на моєму YouTube каналі:

По коду

Перше, що цікавить — навіщо одну і єдину сторінку сайту робити за допомогою клієнтського рендерингу? Портфоліо написане за допомогою Next.js, що автоматично дає можливість роботи з SSR. Тут же з самого верху у нас ‘use client’. Допускаю що причиною була Google Analytics і наступний ефект:

export default function Home() {
 useEffect(() => {
   gtm(events.pageView)
 }, [])

По коду багато розкидано таких викликів функції аналітики. Пораджу використовувати Google Tag Manager на повну і там створювати теги і тригери для кліків. Практично усі події можна налаштувати без внесення змін у код.

Друге — імпорти модулів:

import ScrollDown from '@/app/components/ScrollDown'
import Contact from '@/app/components/sections/Contact'
import Experience from '@/app/components/sections/Experience'
import Footer from '@/app/components/sections/Footer'
import Header from '@/app/components/sections/Header'
import Me from '@/app/components/sections/Me'
import TechStack from '@/app/components/sections/TechStack'
import WhyMe from '@/app/components/sections/WhyMe'
import { gtmId } from '@/app/constants'
import gtm, { events } from '@/app/utils/analytics'
import { GoogleTagManager } from '@next/third-parties/google'
import { useEffect } from 'react'

В папку components можна додати ще один файл index.ts і звідти уже експортувати усі компоненти. Тоді в коді ми зменшимо кількість copy/paste. Детальніше розповідаю у відео.

По імпортах ще одне питання — навіщо в Prettier додавати prettier-plugin-organize-imports якщо порядок цих імпортів не описаний і вони в коді постійно перемішані? І цей плагін, до речі, треба перемістити в dev залежності.

Окремо зауважу про мікс .ts та .js файлів. Якщо уже використовується TypeScript, то додавати .js файли не бажано.

Важливі питання

Чому для стилізації був обраний Tailwind у варіанті Styled Components, реалізований за допомогою twin.macro? Не скажу, що це погано чи добре — просто цікавить аналіз і причини такого рішення. Свої варіанти я озвучую у відео, але хочеться дізнатися від автора.

Для розуміння. Код стилів виглядає ось так:

export const TriggerWrapper = styled.div<StyledAccordion>(() => [
 tw`relative inline-block leading-6 cursor-pointer pr-8`,
 tw`after:transition-transform after:absolute after:top-0 after:w-4 after:h-4 after:right-0.5 after:border-t-4 after:border-l-4`,
 tw`after:border-bgDark dark:after:border-bgLight hover:[&:not([aria-disabled])]:after:border-primary`,
 ({ $isOpen }) =>
   $isOpen ? tw`after:rotate-45 after:top-2` : tw`after:rotate-[225deg]`,
])

export const ContentWrapper = styled.div<StyledAccordion>(() => [
 tw`overflow-hidden [&[hidden]]:block transition-[max-height] duration-[3s]`,
 ({ $isOpen }) =>
   $isOpen
     ? tw`max-h-[9999px]`
     : // hide with max-height + fix close animation delay
       tw`max-h-0 duration-[1s] ease-[cubic-bezier(0,1,0,1)]`,
])

Серверні компоненти NextJS неповноцінно працюють з Styled Components. Про це є попередження на сайті.

Ще одне питання, що мене цікавить. Чому деякі назви пропсів розпочинаються з знаку $, наприклад $isOpen? Це вимоги бібліотеки twin.macro чи власна ідея? В React нема практики так називати пропси.

Ще є багато питань по хуках, особливо useIsMobile — чи дійсно доцільно його було створювати лише щоб змінювати aria-disabled? В ньому ще й використовується resize лістенер без debounce.

По хуку useForm питань ще більше.

З плюсів

Доданий файл .example.env.local — дає розуміння які змінні оточення потрібно додати.

README.md — не дефолтна. Автор постарався трішки описати проєкт.

Для компонентів описані displayName.

Висновок

Залишилось багато питань «Навіщо?». Зайового коду написано багато. Є складні утиліти, але без юніт тестів. Початківцям це можна пробачити, але ж не Senior-розробнику.

Жду коментарів автора під відео. Попереджаю, що YouTube дуже банить підозрілі, довгі або коментарі з посиланнями. Двічі перевіряйте що ваш коментар додано.

Якщо цікавий чи корисний огляд — підписуйтесь на мій YouTube або слідкуйте за спільнотою в Telegram. Там ще більше корисних матеріалів.

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Вітаю, дякую за огляд, відповів на всі питання під відео. До критики нормально відношусь — те із чим згоден буду виправляти, про інше можна подискутувати)

Чому деякі назви пропсів розпочинаються з знаку $, наприклад $isOpen?

Щоб проп не потрапив до DOM елемента в якості атрибута.
styled-components.com/docs/basics#passed-props

Підписатись на коментарі