--- title: Legjobb gyakorlatok image: /images/user-guide/tips/light-bulb.png --- Header Ez a dokumentum ismerteti azokat a legjobb gyakorlatokat, amelyeket követned kell, amikor a frontend fejlesztésen dolgozol. ## Állapotkezelés React és Recoil kezelik az állapotkezelést a kódbázisban. ### Használja a `useRecoilState`-et az állapot tárolására Jó gyakorlat annyi atomot létrehozni, amennyire szükséged van az állapot tárolásához. Érdemesebb extra atomokat használni, mint túlságosan szorosan tartani a tulajdonságfúrást. ```tsx export const myAtomState = atom({ key: 'myAtomState', default: 'default value', }); export const MyComponent = () => { const [myAtom, setMyAtom] = useRecoilState(myAtomState); return (
setMyAtom(e.target.value)} />
); } ``` ### Ne használja az `useRef`-et az állapot tárolására Kerüld az `useRef` használatát állapot tárolására. Ha állapotot szeretnél tárolni, használd a `useState`-t vagy a `useRecoilState`-et. Nézd meg, hogyan kezeld a re-rajzolásokat [re-rajzolások kezelése](#managing-re-renders) ha úgy érzed, az `useRef`-re van szükséged, hogy elkerülj néhány újra-rajzolást. ## Re-rajzolások kezelése A re-rajzolásokat nehéz lehet kezelni a React-ben. Íme néhány szabály, amelyet követned kell, hogy elkerüld a felesleges újra-rajzolásokat. Tartsd észben, hogy **mindig** elkerülheted a re-rajzolásokat az okok megértésével. ### Dolgozz gyökeri szinten A re-rajzolások elkerülése az új funkciókban könnyebbé vált azáltal, hogy megszüntették azokat gyökeri szinten. A `PageChangeEffect` segédkomponens csak egy `useEffect`-et tartalmaz, ami minden logikát tartalmaz, amit egy lapváltáskor végre kell hajtani. Így tudod, hogy csak egy hely van, ami kiválthat egy újra-rajzolást. ### Mindig gondolkodj kétszer, mielőtt `useEffect`-et adsz a kódbázisodhoz A re-rajzolásokat gyakran szükségtelen `useEffect` okozza. Gondold meg, hogy szükséged van-e `useEffect`-re, vagy áthelyezheted a logikát egy eseménykezelő függvénybe. Általában könnyen áthelyezheted a logikát egy `handleClick` vagy `handleChange` függvénybe. Könyvtárakban, például az Apollóban is megtalálhatóak: `onCompleted`, `onError`, stb. ### Használj testvérkomponenst az `useEffect` vagy adatlekérő logika kiterjesztésére Ha úgy érzed, `useEffect`-et kell hozzáadnod a gyökérkomponensedhez, fontold meg egy segédkomponensbe való áthelyezését. Ugyanez vonatkozik az adatlekérő logikára is, például Apollo horgokkal. ```tsx // ❌ Bad, will cause re-renders even if data is not changing, // because useEffect needs to be re-evaluated export const PageComponent = () => { const [data, setData] = useRecoilState(dataState); const [someDependency] = useRecoilState(someDependencyState); useEffect(() => { if(someDependency !== data) { setData(someDependency); } }, [someDependency]); return
{data}
; }; export const App = () => ( ); ``` ```tsx // ✅ Good, will not cause re-renders if data is not changing, // because useEffect is re-evaluated in another sibling component export const PageComponent = () => { const [data, setData] = useRecoilState(dataState); return
{data}
; }; export const PageData = () => { const [data, setData] = useRecoilState(dataState); const [someDependency] = useRecoilState(someDependencyState); useEffect(() => { if(someDependency !== data) { setData(someDependency); } }, [someDependency]); return <>; }; export const App = () => ( ); ``` ### Használj Recoil család állapotokat és Recoil családi szelektorokat A Recoil családi állapotok és szelektorok nagyszerű módjai az újra-rajzolások elkerülésének. Hasznosak, ha egy lista elemeit kell tárolni. ### Nem szabad `React.memo(MyComponent)`-et használni Kerüld a `React.memo()` használatát, mert ez nem oldja meg az újra-rajzolás okát, hanem megszakítja az újra-rajzolási láncot, ami váratlan viselkedéshez vezethet és nehezítheti a kód átalakítását. ### Korlátozd a `useCallback` vagy `useMemo` használatát Gyakran szükségtelenek, és megnehezítik a kód olvasását és karbantartását a szinte észrevehetetlen teljesítménynövekedésért cserébe. ## Konzol.logok A `console.log` utasítások értékesek a fejlesztés során, mivel valós idejű betekintést nyújtanak a változók értékébe és a kódfolyamatba. De ha a gyártási kódban hagyják őket, számos problémához vezethet: 1. **Teljesítmény**: A túlzott naplózás befolyásolhatja a futásidejű teljesítményt, különösen kliens oldali alkalmazásokban. 2. **Biztonság**: Érzékeny adatok naplózása kritikus információkat tárhat fel bárki számára, aki ellenőrzi a böngésző konzolját. 3. **Tisztaság**: A konzol naplókkal való feltöltése elfedheti a fontos figyelmeztetéseket vagy hibákat, amelyekre a fejlesztőknek vagy eszközöknek szüksége van. 4. **Szakmaiság**: Ha a végfelhasználók vagy ügyfelek ellenőrzik a konzolt, és számos naplónyilatkozatot látnak, megkérdőjelezhetik a kód minőségét és csiszoltságát. Győződj meg arról, hogy minden `console.log`-ot eltávolítasz, mielőtt a kódot a gyártásba juttatnád. ## Elnevezés ### Változónév adása A változóneveknek pontosan kell ábrázolniuk a változó célját vagy funkcióját. #### A probléma az általános nevekkel Az általános nevek a programozásban nem ideálisak, mivel hiányzik a specifikációjuk, ami bizonytalansághoz és a kód olvashatóságának csökkenéséhez vezet. Az ilyen nevek nem tudják közvetíteni a változó vagy függvény célját, ami megnehezíti a fejlesztők számára a kód szándékának megértését anélkül, hogy mélyebben kutatnának. Ez megnövekedett hibakeresési időt, nagyobb hajlandóságot a hibákra és nehézségeket okoz a karbantartásban és az együttműködésben. Eközben a leíró elnevezés megkönnyíti a kód önmgot és egyszerűbbé teszi a navigálást, javítva a kódminőséget és a fejlesztői termelékenységet. ```tsx // ❌ Bad, uses a generic name that doesn't communicate its // purpose or content clearly const [value, setValue] = useState(''); ``` ```tsx // ✅ Good, uses a descriptive name const [email, setEmail] = useState(''); ``` #### Néhány szó, amit el kell kerülni a változónevekben - próba ### Eseménykezelők Az eseménykezelők neve `handle`-lel kell kezdődjön, míg az `on` előtagot az események nevének kell használni az összetevők tulajdonságaiban. ```tsx // ❌ Bad const onEmailChange = (val: string) => { // ... }; ``` ```tsx // ✅ Good const handleEmailChange = (val: string) => { // ... }; ``` ## Opcionális tulajdonságok Kerüld el az alapértelmezett érték átadását egy opcionális tulajdonsághoz. **PÉLDA** Tekintsd meg a lent meghatározott `EmailField` komponenst: ```tsx type EmailFieldProps = { value: string; disabled?: boolean; }; const EmailField = ({ value, disabled = false }: EmailFieldProps) => ( ); ``` **Használat** ```tsx // ❌ Bad, passing in the same value as the default value adds no value const Form = () => ; ``` ```tsx // ✅ Good, assumes the default value const Form = () => ; ``` ## Összetevő tulajdonságként Próbálj meg lehetőleg kezeletlen komponenseket propsként átadni, így a gyermekek eldönthetik, hogy milyen propsokat kell továbbítaniuk. A leggyakoribb példa erre az ikon komponensek: ```tsx const SomeParentComponent = () => ; // In MyComponent const MyComponent = ({ MyIcon }: { MyIcon: IconComponent }) => { const theme = useTheme(); return (
) }; ``` Ahhoz, hogy a React felismerje, hogy a komponens egy komponens, PascalCase-t kell használni, hogy később ``-tal lehessen példányosítani. ## Prop fúrás: Tartsd minimális szinten A prop fúrás a React kontextusban arra utal, hogy hogyan adod át az állapotváltozókat és azok beállítóit több komponensrétegen keresztül, még ha a köztes elemek nem is használják őket. Habár néha szükséges, a túlzott prop fúrás ahhoz vezethet, hogy: 1. **Olvashatóság csökkenése**: Egy prop eredetét vagy felhasználási helyét követni bonyolulttá válhat egy mélyen beágyazott komponens szerkezetben. 2. **Fenntartási kihívások**: Egy komponens prop szerkezetének megváltoztatása több komponens módosítását is igényelheti, még akkor is, ha közvetlenül nem használják a propot. 3. **Komponens újrahasznosíthatóság csökkenése**: Egy komponens, amely sok propot csak átadás céljából kap, kevésbé lesz általános célú és nehezebben újrahasznosítható különböző kontextusokban. Ha úgy érzed, hogy túlzottan használod a prop fúrást, nézd meg az [állapotkezelési legjobb gyakorlatokat](#state-management). ## Importálás Az importálás során válaszd a kijelölt álnév használatát a teljes vagy relatív útvonal helyett. **Kezelőnevek** ```js { alias: { "~": path.resolve(__dirname, "src"), "@": path.resolve(__dirname, "src/modules"), "@testing": path.resolve(__dirname, "src/testing"), }, } ``` **Használat** ```tsx // ❌ Bad, specifies the entire relative path import { CatalogDecorator } from '../../../../../testing/decorators/CatalogDecorator'; import { ComponentDecorator } from '../../../../../testing/decorators/ComponentDecorator'; ``` ```tsx // ✅ Good, utilises the designated aliases import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator'; import { ComponentDecorator } from 'twenty-ui/testing'; ``` ## Séma érvényesítés [Zod](https://github.com/colinhacks/zod) az érzelem nélküli objektumok sémavezérlője. ```js const validationSchema = z .object({ exist: z.boolean(), email: z .string() .email('Email must be a valid email'), password: z .string() .regex(PASSWORD_REGEX, 'Password must contain at least 8 characters'), }) .required(); type Form = z.infer; ``` ## Törő változások Mindig végezz alapos manuális tesztelést a folytatás előtt, hogy garantáld, hogy a módosítások nem okoznak hibákat máshol, tekintettel arra, hogy a tesztek még nem kerültek széleskörűen integrálásra.