> ## Documentation Index
> Fetch the complete documentation index at: https://docs.twenty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# En İyi Uygulamalar

Bu belge, ön yüz üzerinde çalışırken takip etmeniz gereken en iyi uygulamaları özetler.

## Durum Yönetimi

React ve Jotai, kod tabanında durumu yönetir.

### Durumu depolamak için Jotai atomlarını kullanın

Durumunuzu depolamak için ihtiyaç duyduğunuz kadar atom oluşturmak iyi bir uygulamadır.

<Warning>
  Prop drilling ile gereğinden fazla sade olmaya çalışmaktansa, fazladan atom kullanmak daha iyidir.
</Warning>

```tsx theme={null}
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';

export const myAtomState = createAtomState<string>({
  key: 'myAtomState',
  defaultValue: 'default value',
});

export const MyComponent = () => {
  const [myAtom, setMyAtom] = useAtomState(myAtomState);

  return (
    <div>
      <input
        value={myAtom}
        onChange={(e) => setMyAtom(e.target.value)}
      />
    </div>
  );
}
```

### Durum saklamak için `useRef` kullanmayın.

Durum saklamak için `useRef` kullanmaktan kaçının.

Durum saklamak istiyorsanız, `useState` veya `useAtomState` ile Jotai atomlarını kullanmalısınız.

Bazı yeniden render edilmelerin olmasını önlemek için `useRef`'e ihtiyacınız varmış gibi hissediyorsanız, [yeniden render yönetimi](#managing-re-renders) konusuna bakın.

## Yeniden render yönetimi

React'ta yeniden render'ları yönetmek zor olabilir.

Gereksiz yeniden render'ları önlemek için izlenecek bazı kurallar burada.

Yeniden render'ları **her zaman** önleyebileceğinizi unutmayın, olayların nedenini anlayarak.

### Kök seviyesinde çalışın

Yeni özelliklerde yeniden render'ları önlemek, onları kök seviyesinde ortadan kaldırarak artık kolaylaştı.

`PageChangeEffect` yan bileşeni, sayfa değişikliği sırasında yürütülecek tüm mantığı içeren tek bir `useEffect` barındırır.

Bu şekilde, yalnızca bir yerin yeniden render tetikleyebileceğini bilirsiniz.

### Kod tabanına `useEffect` eklemeden önce iki kez düşünün.

Yeniden render'lar çoğunlukla gereksiz `useEffect`'lerden kaynaklanır.

`useEffect`'e ihtiyacınız olup olmadığını düşünmelisiniz ya da mantığı bir olay işleyici fonksiyonuna taşıyabilirsiniz.

Genellikle mantığı `handleClick` veya `handleChange` gibi fonksiyonlara taşımayı kolay bulursunuz.

Bunları `onCompleted`, `onError`, vb. gibi Apollo kitaplıklarında da bulabilirsiniz.

### `useEffect` veya veri çekme mantığını çıkarmak için bir yan bileşen kullanın.

Kök bileşenize bir `useEffect` eklemeniz gerektiğini hissediyorsanız, bunu bir yan bileşene çıkarmayı düşünmelisiniz.

Aynısını Apollo kancaları ile veri çekme mantığı için de uygulayabilirsiniz.

```tsx theme={null}
// ❌ Bad, will cause re-renders even if data is not changing,
//    because useEffect needs to be re-evaluated
export const PageComponent = () => {
  const [data, setData] = useAtomState(dataState);
  const [someDependency] = useAtomState(someDependencyState);

  useEffect(() => {
    if(someDependency !== data) {
      setData(someDependency);
    }
  }, [someDependency]);

  return <div>{data}</div>;
};

export const App = () => (
  <PageComponent />
);
```

```tsx theme={null}
// ✅ 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] = useAtomState(dataState);

  return <div>{data}</div>;
};

export const PageData = () => {
  const [data, setData] = useAtomState(dataState);
  const [someDependency] = useAtomState(someDependencyState);

  useEffect(() => {
    if(someDependency !== data) {
      setData(someDependency);
    }
  }, [someDependency]);

  return <></>;
};

export const App = () => (
  <>
    <PageData />
    <PageComponent />
  </>
);
```

### Atom aile durumlarını ve seçimcilerini kullanın

Atom aile durumları ve seçimcileri, yeniden render'ları önlemenin harika bir yoludur.

Bir öğe listesini saklamanız gerektiğinde kullanılabilirdir.

### `React.memo(MyComponent)` kullanmamalısınız.

`React.memo()` kullanmaktan kaçının çünkü bu yeniden render'ın nedenini çözmez, bunun yerine yeniden render zincirini kırar, bu da beklenmeyen davranışlara yol açabilir ve kodun yeniden faktör edilmesini çok zor hale getirebilir.

### `useCallback` veya `useMemo` kullanımını sınırlayın.

Genellikle gerekli değildir ve performans kazanımı farkedilemeyecek kadar az olduğu için kodun okunmasını ve bakımını zorlaştırır.

## Console.log'lar

`console.log` ifadeleri geliştirirken değerlidir, değişken değerleri ve kod akışı hakkında gerçek zamanlı yanıtlar sağlar. Ancak, üretim kodunda bırakmak çeşitli sorunlara yol açabilir:

1. **Performans**: Aşırı loglama, özellikle istemci tarafı uygulamalarda çalışma zamanı performansını etkileyebilir.

2. **Güvenlik**: Hassas verileri loglama, tarayıcı konsolunu inceleyen herkes için kritik bilgilerin açığa çıkmasına neden olabilir.

3. **Temizlik**: Konsolu loglarla doldurmak, geliştiricilerin veya araçların görmesi gereken önemli uyarıları veya hataları gizleyebilir.

4. **Profesyonellik**: Konsolu kontrol eden son kullanıcılar veya müşteriler, birçok log ifadesi gördüğünde kodun kalitesini ve detaycılığını sorgulayabilir.

Kodunuzu üretime taşımadan önce tüm `console.log`ları kaldırdığınızdan emin olun.

## İsimlendirme

### Değişken Adlandırma

Değişken adları değişkenin amacını veya işlevini doğru bir şekilde tanımlamalıdır.

#### Genel adlar sorunu

Programlamada genel adlar ideal değildir çünkü kesinlik eksikliği nedeniyle belirsizlik ve kod okunabilirliğinin azalmasına neden olabilir. Bu tür adlar, değişkenin veya fonksiyonun amacını iletmede başarısız olur, geliştiricilerin kodun amacını daha derin bir araştırma yapmadan anlamalarını zorlaştırır. Bu, artan hata ayıklama süresi, hatalara eğilimli olma ve bakım ve işbirliği zorluklarına yol açabilir. Öte yandan, açıklayıcı adlandırma, kodu kendi kendini açıklayıcı hale getirir ve gezilebilirliği artırarak kod kalitesini ve geliştirici verimliliğini artırır.

```tsx theme={null}
// ❌ Bad, uses a generic name that doesn't communicate its
//    purpose or content clearly
const [value, setValue] = useState('');
```

```tsx theme={null}
// ✅ Good, uses a descriptive name
const [email, setEmail] = useState('');
```

#### Değişken adlarında kaçınılması gereken bazı kelimeler

* kukla

### Olay işleyicileri

Olay işleyici adları `handle` ile başlamalı, bileşen props'larında olayları adlandırmak için `on` bir ön ek olarak kullanılmaktadır.

```tsx theme={null}
// ❌ Bad
const onEmailChange = (val: string) => {
  // ...
};
```

```tsx theme={null}
// ✅ Good
const handleEmailChange = (val: string) => {
  // ...
};
```

## Opsiyonel Props

Opsiyonel bir prop için varsayılan değeri geçmekten kaçının.

**ÖRNEK**

Aşağıda tanımlanan `EmailField` bileşeni alın:

```tsx theme={null}
type EmailFieldProps = {
  value: string;
  disabled?: boolean;
};

const EmailField = ({ value, disabled = false }: EmailFieldProps) => (
  <TextInput value={value} disabled={disabled} fullWidth />
);
```

**Kullanım**

```tsx theme={null}
// ❌ Bad, passing in the same value as the default value adds no value
const Form = () => <EmailField value="username@email.com" disabled={false} />;
```

```tsx theme={null}
// ✅ Good, assumes the default value
const Form = () => <EmailField value="username@email.com" />;
```

## Bileşenleri props olarak geçirme

Mümkün olduğunca, bileşenleri kendi içinde istemsiz geçen bileşenler olarak gönderin, böylece çocuklar hangi props'ları geçmeleri gerektiğine kendileri karar verebilirler.

Bunun en yaygın örneği simge bileşenleridir:

```tsx theme={null}
const SomeParentComponent = () => <MyComponent Icon={MyIcon} />;

// In MyComponent
const MyComponent = ({ MyIcon }: { MyIcon: IconComponent }) => {
  const theme = useTheme();

  return (
    <div>
      <MyIcon size={theme.icon.size.md}>
    </div>
  )
};
```

React'in bir bileşeni bileşen olarak anlaması için PascalCase kullanmalısınız, böylece daha sonra `<MyIcon>` ile örnekleyebilirsiniz.

## Prop Taşıma: Minimumda Tutun

React bağlamında prop taşıma, durum değişkenlerini ve ayarlayıcılarını, aracı bileşenler kullanmasalar bile birçok bileşen katmanı aracılığıyla aktarma uygulamasına atıfta bulunur. Bazen gerekli olmakla birlikte, aşırı prop taşıma şu durumlara yol açabilir:

1. **Azalan Okunabilirlik**: Bir prop'un nereden kaynaklandığını veya nerede kullanıldığını izlemek, derin bir şekilde iç içe geçmiş bir bileşen yapısında karışık hale gelebilir.

2. **Bakım Zorlukları**: Bir bileşenin prop yapısındaki değişiklikler, prop'u doğrudan kullanmasalar bile, birden fazla bileşende ayarlamalar yapılmasını gerektirebilir.

3. **Azalan Bileşen Yeniden Kullanılabilirliği**: Çok fazla props'u yalnızca aşağıya aktarma amacıyla alan bir bileşen, daha az genel amaçlı hale gelir ve farklı bağlamlarda yeniden kullanılması zorlaşır.

Aşırı prop taşıma kullanıyorsanız, [durum yönetimi en iyi uygulamalarına](#state-management) bakın.

## İçe Aktarımlar

İçe aktarırken, tüm veya göreli yolları belirtmek yerine belirlenen takma adları tercih edin.

**Takma Adlar**

```js theme={null}
{
  alias: {
    "~": path.resolve(__dirname, "src"),
    "@": path.resolve(__dirname, "src/modules"),
    "@testing": path.resolve(__dirname, "src/testing"),
  },
}
```

**Kullanım**

```tsx theme={null}
// ❌ Bad, specifies the entire relative path
import {
  CatalogDecorator
} from '../../../../../testing/decorators/CatalogDecorator';
import {
  ComponentDecorator
} from '../../../../../testing/decorators/ComponentDecorator';
```

```tsx theme={null}
// ✅ Good, utilises the designated aliases
import { CatalogDecorator } from '~/testing/decorators/CatalogDecorator';
import { ComponentDecorator } from 'twenty-ui/testing';
```

## Şema Doğrulama

[Zod](https://github.com/colinhacks/zod), tiplenmemiş nesneler için bir şema doğrulayıcıdır:

```js theme={null}
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>;
```

## Geriye Dönük Uyumsuz Değişiklikler

Testler henüz kapsamlı bir şekilde entegre edilmediği için, ilerlemeden önce yapılan değişikliklerin başka yerlerde bozulmalara neden olmadığından emin olmak için her zaman kapsamlı manuel testler yapın.
