Files
twenty/packages/twenty-docs/l/no/developers/frontend-development/best-practices-front.mdx
T
github-actions[bot] 8cadd00d34 i18n - translations (#15799)
Created by Github action

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: github-actions <github-actions@twenty.com>
2025-11-13 16:34:00 +01:00

334 lines
9.8 KiB
Plaintext

---
title: Beste praksis
image: /images/user-guide/tips/light-bulb.png
---
<Frame>
<img src="/images/user-guide/tips/light-bulb.png" alt="Header" />
</Frame>
Dette dokumentet skisserer de beste praksisene du bør følge når du jobber på frontend.
## Tilstandshåndtering
React og Recoil håndterer tilstandshåndtering i kodebasen.
### Bruk `useRecoilState` for å lagre tilstand
Det er en god praksis å lage så mange atomer som du trenger for å lagre tilstanden din.
<Warning>
Det er bedre å bruke ekstra atomer enn å prøve å være for konsis med å bore props.
</Warning>
```tsx
export const myAtomState = atom({
key: 'myAtomState',
default: 'default value',
});
export const MyComponent = () => {
const [myAtom, setMyAtom] = useRecoilState(myAtomState);
return (
<div>
<input
value={myAtom}
onChange={(e) => setMyAtom(e.target.value)}
/>
</div>
);
}
```
### Ikke bruk `useRef` for å lagre tilstand
Unngå å bruke `useRef` for å lagre tilstand.
Hvis du vil lagre tilstand, bør du bruke `useState` eller `useRecoilState`.
Se [hvordan håndtere omrendringer](#managing-re-renders) hvis du føler at du trenger `useRef` for å forhindre at noen omrendringer skjer.
## Håndtere omrendringer
Omrendringer kan være vanskelige å håndtere i React.
Her er noen regler å følge for å unngå unødvendige omrendringer.
Husk at du **alltid** kan unngå omrendringer ved å forstå deres årsak.
### Arbeid på rotnivå
Unngåelse av omrendringer i nye funksjoner er nå gjort enkelt ved å eliminere dem på rotnivå.
The `PageChangeEffect` sidecar component contains just one `useEffect` that holds all the logic to execute on a page change.
På denne måten vet du at det er bare ett sted som kan utløse en omrendering.
### Tenk deg nøye om før du legger til `useEffect` i din kodebase
Omrendringer er ofte forårsaket av unødvendig `useEffect`.
Du bør vurdere om du trenger `useEffect`, eller om du kan flytte logikken til en hendelseshåndtererfunksjon.
Du vil generelt finne det enkelt å flytte logikken til en `handleClick` eller `handleChange`-funksjon.
Du kan også finne dem i biblioteker som Apollo: `onCompleted`, `onError`, osv.
### Bruk en søskenkomponent for å trekke ut `useEffect` eller datahentingslogikk
Hvis du føler at du trenger å legge til en `useEffect` i din rotkomponent, bør du vurdere å trekke den ut i en sidevognkomponent.
Du kan bruke det samme for datahentingslogikk, med Apollo hooks.
```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 <div>{data}</div>;
};
export const App = () => (
<RecoilRoot>
<PageComponent />
</RecoilRoot>
);
```
```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 <div>{data}</div>;
};
export const PageData = () => {
const [data, setData] = useRecoilState(dataState);
const [someDependency] = useRecoilState(someDependencyState);
useEffect(() => {
if(someDependency !== data) {
setData(someDependency);
}
}, [someDependency]);
return <></>;
};
export const App = () => (
<RecoilRoot>
<PageData />
<PageComponent />
</RecoilRoot>
);
```
### Bruk recoil familietilstander og recoil familieselektorer
Recoil familietilstander og selektorer er en flott måte å unngå omrendringer på.
De er nyttige når du trenger å lagre en liste over elementer.
### Du bør ikke bruke `React.memo(MyComponent)`
Unngå bruk av `React.memo()` fordi det ikke løser årsaken til omrenderingen, men i stedet bryter omrenderingskjeden, noe som kan føre til uventet oppførsel og gjøre koden veldig vanskelig å refaktorere.
### Begrens bruken av `useCallback` eller `useMemo`
De er ofte ikke nødvendige og vil gjøre koden vanskeligere å lese og vedlikeholde for en gevinst i ytelse som er umerkelig.
## Console.logs
`console.log` setninger er verdifulle under utvikling, og tilbyr sanntidsinnsikt i variabelverdier og kodeflyt. Men å la dem være i produksjonskode kan føre til flere problemer:
1. **Ytelse**: Overdreven logging kan påvirke kjøringsytelsen, spesielt på klientapplikasjoner.
2. **Sikkerhet**: Logging av sensitiv data kan avsløre kritisk informasjon til alle som inspiserer nettleserens konsoll.
3. **Ryddighet**: Å fylle opp konsollen med logger kan skjule viktige advarsler eller feil som utviklere eller verktøy trenger å se.
4. **Profesjonalitet**: Sluttbrukere eller kunder som sjekker konsollen og ser en mengde loggutsagn kan stille spørsmål ved kvaliteten og finishen av koden.
Forsikre deg om at du fjerner alle `console.logs` før du skyver koden til produksjon.
## Navngiving
### Variabelnavngiving
Variabelnavn bør presist beskrive variablens hensikt eller funksjon.
#### Problemet med generiske navn
Generiske navn i programmering er ikke ideelle fordi de mangler spesifisitet, noe som fører til tvetydighet og redusert kodelesbarhet. Slike navn klarer ikke å formidle variabelen eller funksjonens hensikt, noe som gjør det utfordrende for utviklere å forstå kodenes intensjon uten dypere undersøkelser. Dette kan føre til økt feilsøkingstid, høyere sårbarhet for feil, og vansker ved vedlikehold og samarbeid. I mellomtiden gjør beskrivende navngiving koden selvforklarende og lettere å navigere, og øker kodekvaliteten og utviklerens produktivitet.
```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('');
```
#### Noen ord å unngå i variabelnavn
- dummy
### Hendelseshåndterere
Hendelseshåndterernes navn bør starte med `handle`, mens `on` er et prefiks brukt for å navngi hendelser i komponentprops.
```tsx
// ❌ Bad
const onEmailChange = (val: string) => {
// ...
};
```
```tsx
// ✅ Good
const handleEmailChange = (val: string) => {
// ...
};
```
## Valgfrie Props
Unngå å sende den standardverdien for en valgfri prop.
**EKSEMPEL**
Ta `EmailField` komponenten definert nedenfor:
```tsx
type EmailFieldProps = {
value: string;
disabled?: boolean;
};
const EmailField = ({ value, disabled = false }: EmailFieldProps) => (
<TextInput value={value} disabled={disabled} fullWidth />
);
```
**Bruk**
```tsx
// ❌ Bad, passing in the same value as the default value adds no value
const Form = () => <EmailField value="username@email.com" disabled={false} />;
```
```tsx
// ✅ Good, assumes the default value
const Form = () => <EmailField value="username@email.com" />;
```
## Komponent som props
Prøv så mye som mulig å sende ikke-instanserte komponenter som props, slik at barn kan bestemme selv hvilke props de trenger å sende.
Det vanligste eksemplet på dette er ikonekomponenter.
```tsx
const SomeParentComponent = () => <MyComponent Icon={MyIcon} />;
// In MyComponent
const MyComponent = ({ MyIcon }: { MyIcon: IconComponent }) => {
const theme = useTheme();
return (
<div>
<MyIcon size={theme.icon.size.md}>
</div>
)
};
```
For at React skal forstå at komponenten er en komponent, må du bruke store bokstaver, for senere å instansiere den med `<MyIcon>`
## Prop-gjennomgang: Hold det minimalt
I React-sammenheng refererer prop-gjennomgang til praksisen med å sende tilstandsvariabler og deres settere gjennom mange komponentlag, selv om mellomliggende komponenter ikke bruker dem. Selv om det noen ganger er nødvendig, kan overdreven prop-gjennomgang føre til:
1. **Redusert Lesbarhet**: Å spore hvor en prop stammer fra eller hvor den brukes kan bli komplisert i en dypt nestet komponentstruktur.
2. **Vedlikeholdsutfordringer**: Endringer i en komponents prop-struktur kan kreve justeringer i flere komponenter, selv om de ikke direkte bruker propen.
3. **Redusert Komponentgjenbruk**: En komponent som mottar mange props kun for å sende dem videre blir mindre allsidig og vanskeligere å gjenbruke i forskjellige sammenhenger.
Hvis du føler at du bruker overdreven prop-gjennomgang, se [beste praksis for tilstandshåndtering](#state-management).
## Importer
Ved import, velg de angitte aliasene fremfor å spesifisere komplette eller relative stier.
**Håndtak Aliaser**
```js
{
alias: {
"~": path.resolve(__dirname, "src"),
"@": path.resolve(__dirname, "src/modules"),
"@testing": path.resolve(__dirname, "src/testing"),
},
}
```
**Bruk**
```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';
```
## Schema-validering
[Zod](https://github.com/colinhacks/zod) er skjema-valideren for utypede objekter.
```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<typeof validationSchema>;
```
## Kritiske Endringer
Utfør alltid grundig manuell testing før du går videre for å sikre at modifikasjoner ikke har forårsaket forstyrrelser andre steder, gitt at tester ennå ikke er omfattende integrert.