Türkçe

React özel hook'larını kullanarak bileşen mantığını nasıl çıkaracağınızı ve yeniden kullanacağınızı öğrenin, böylece kodun sürdürülebilirliğini, test edilebilirliğini ve genel uygulama mimarisini iyileştirin.

React Özel Hook'lar: Yeniden Kullanılabilirlik için Bileşen Mantığını Çıkarma

React hook'ları, React bileşenlerini yazma şeklimizde devrim yaratarak, durumu ve yan etkileri yönetmek için daha zarif ve verimli bir yol sunar. Mevcut çeşitli hook'lar arasında, özel hook'lar bileşen mantığını çıkarmak ve yeniden kullanmak için güçlü bir araç olarak öne çıkıyor. Bu makale, React özel hook'larını anlamak ve uygulamak için kapsamlı bir kılavuz sağlayarak, daha sürdürülebilir, test edilebilir ve ölçeklenebilir uygulamalar oluşturmanızı sağlar.

React Özel Hook'ları Nelerdir?

Özünde, özel bir hook, adı "use" ile başlayan ve diğer hook'ları çağırabilen bir JavaScript fonksiyonudur. Bileşen mantığını yeniden kullanılabilir fonksiyonlara çıkarmanıza olanak tanır, böylece kod tekrarını ortadan kaldırır ve daha temiz bir bileşen yapısını teşvik eder. Normal React bileşenlerinden farklı olarak, özel hook'lar herhangi bir UI oluşturmaz; sadece mantığı kapsüllerler.

Bunları, React durumuna ve yaşam döngüsü özelliklerine erişebilen yeniden kullanılabilir fonksiyonlar olarak düşünün. Yüksek dereceli bileşenlere veya genellikle okunması ve bakımı zor olan bir koda yol açabilen render özelliklerine başvurmadan, farklı bileşenler arasında durum bilgisi olan mantığı paylaşmanın harika bir yoludur.

Neden Özel Hook'lar Kullanmalıyız?

Özel hook'lar kullanmanın sayısız faydası vardır:

İlk Özel Hook'unuzu Oluşturma

Pratik bir örnekle özel bir hook'un oluşturulmasını ve kullanımını gösterelim: Bir API'den veri çekme.

Örnek: useFetch - Bir Veri Çekme Hook'u

React uygulamanızda farklı API'lerden sık sık veri çekmeniz gerektiğini hayal edin. Her bileşende fetch mantığını tekrarlamak yerine, bir useFetch hook'u oluşturabilirsiniz.


import { useState, useEffect } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const abortController = new AbortController();
    const signal = abortController.signal;

    const fetchData = async () => {
      setLoading(true);
      try {
        const response = await fetch(url, { signal: signal });
        if (!response.ok) {
          throw new Error(`HTTP error! Status: ${response.status}`);
        }
        const json = await response.json();
        setData(json);
        setError(null); // Clear any previous errors
      } catch (error) {
        if (error.name === 'AbortError') {
          console.log('Fetch aborted');
        } else {
          setError(error);
        }
        setData(null); // Clear any previous data
      } finally {
        setLoading(false);
      }
    };

    fetchData();

    return () => {
      abortController.abort(); // Cleanup function to abort the fetch on unmount or URL change
    };
  }, [url]); // Re-run effect when the URL changes

  return { data, loading, error };
}

export default useFetch;

Açıklama:

useFetch Hook'unu Bir Bileşende Kullanma

Şimdi, bu özel hook'u bir React bileşeninde nasıl kullanacağımızı görelim:


import React from 'react';
import useFetch from './useFetch';

function UserList() {
  const { data: users, loading, error } = useFetch('https://jsonplaceholder.typicode.com/users');

  if (loading) return <p>Kullanıcılar yükleniyor...</p>;
  if (error) return <p>Hata: {error.message}</p>;
  if (!users) return <p>Kullanıcı bulunamadı.</p>;

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name} ({user.email})</li>
      ))}
    </ul>
  );
}

export default UserList;

Açıklama:

Gelişmiş Özel Hook Kalıpları

Basit veri çekmenin ötesinde, özel hook'lar daha karmaşık mantığı kapsüllemek için kullanılabilir. İşte birkaç gelişmiş kalıp:

1. useReducer ile Durum Yönetimi

Daha karmaşık durum yönetimi senaryoları için, özel hook'ları useReducer ile birleştirebilirsiniz. Bu, durum geçişlerini daha öngörülebilir ve düzenli bir şekilde yönetmenizi sağlar.


import { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

function useCounter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  const increment = () => dispatch({ type: 'increment' });
  const decrement = () => dispatch({ type: 'decrement' });

  return { count: state.count, increment, decrement };
}

export default useCounter;

Kullanım:


import React from 'react';
import useCounter from './useCounter';

function Counter() {
  const { count, increment, decrement } = useCounter();

  return (
    <div>
      <p>Sayım: {count}</p>
      <button onClick={increment}>Artır</button>
      <button onClick={decrement}>Azalt</button>
    </div>
  );
}

export default Counter;

2. useContext ile Bağlam Entegrasyonu

Özel hook'lar, React Bağlamına erişimi basitleştirmek için de kullanılabilir. Bileşenlerinizde doğrudan useContext kullanmak yerine, bağlam erişim mantığını kapsülleyen özel bir hook oluşturabilirsiniz.


import { useContext } from 'react';
import { ThemeContext } from './ThemeContext'; // Bir ThemeContext'iniz olduğunu varsayalım

function useTheme() {
  return useContext(ThemeContext);
}

export default useTheme;

Kullanım:


import React from 'react';
import useTheme from './useTheme';

function MyComponent() {
  const { theme, toggleTheme } = useTheme();

  return (
    <div style={{ backgroundColor: theme.background, color: theme.color }}>
      <p>Bu benim bileşenim.</p>
      <button onClick={toggleTheme}>Temayı Değiştir</button>
    </div>
  );
}

export default MyComponent;

3. Debouncing ve Throttling

Debouncing ve throttling, bir fonksiyonun yürütülme hızını kontrol etmek için kullanılan tekniklerdir. Özel hook'lar, bu mantığı kapsüllemek için kullanılabilir ve bu teknikleri olay işleyicilerine uygulamayı kolaylaştırır.


import { useState, useEffect, useRef } from 'react';

function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]);

  return debouncedValue;
}

export default useDebounce;

Kullanım:


import React, { useState } from 'react';
import useDebounce from './useDebounce';

function SearchInput() {
  const [searchValue, setSearchValue] = useState('');
  const debouncedSearchValue = useDebounce(searchValue, 500); // 500ms için debounce

  useEffect(() => {
    // debouncedSearchValue ile arama yap
    console.log('Aranıyor:', debouncedSearchValue);
    // console.log'u gerçek arama mantığınızla değiştirin
  }, [debouncedSearchValue]);

  const handleChange = (event) => {
    setSearchValue(event.target.value);
  };

  return (
    <input
      type="text"
      value={searchValue}
      onChange={handleChange}
      placeholder="Ara..."
    />
  );
}

export default SearchInput;

Özel Hook'lar Yazmak için En İyi Uygulamalar

Özel hook'larınızın etkili ve sürdürülebilir olduğundan emin olmak için şu en iyi uygulamaları izleyin:

Küresel Hususlar

Küresel bir kitle için uygulamalar geliştirirken, aşağıdakileri aklınızda bulundurun:

Örnek: Özel Bir Hook ile Uluslararasılaştırılmış Tarih Biçimlendirmesi


import { useState, useEffect } from 'react';
import { DateTimeFormat } from 'intl';

function useFormattedDate(date, locale) {
  const [formattedDate, setFormattedDate] = useState('');

  useEffect(() => {
    try {
      const formatter = new DateTimeFormat(locale, {
        year: 'numeric',
        month: 'long',
        day: 'numeric',
      });
      setFormattedDate(formatter.format(date));
    } catch (error) {
      console.error('Tarih biçimlendirme hatası:', error);
      setFormattedDate('Geçersiz Tarih');
    }
  }, [date, locale]);

  return formattedDate;
}

export default useFormattedDate;

Kullanım:


import React from 'react';
import useFormattedDate from './useFormattedDate';

function MyComponent() {
  const today = new Date();
  const enDate = useFormattedDate(today, 'en-US');
  const frDate = useFormattedDate(today, 'fr-FR');
  const deDate = useFormattedDate(today, 'de-DE');

  return (
    <div>
      <p>ABD Tarihi: {enDate}</p>
      <p>Fransız Tarihi: {frDate}</p>
      <p>Alman Tarihi: {deDate}</p>
    </div>
  );
}

export default MyComponent;

Sonuç

React özel hook'ları, bileşen mantığını çıkarmak ve yeniden kullanmak için güçlü bir mekanizmadır. Özel hook'ları kullanarak daha temiz, daha sürdürülebilir ve test edilebilir kod yazabilirsiniz. React konusunda daha yetkin hale geldikçe, özel hook'larda uzmanlaşmak karmaşık ve ölçeklenebilir uygulamalar oluşturma yeteneğinizi önemli ölçüde artıracaktır. Etkili ve çeşitli bir kitle için erişilebilir olduklarından emin olmak için özel hook'lar geliştirirken en iyi uygulamaları izlemeyi ve küresel faktörleri göz önünde bulundurmayı unutmayın. Özel hook'ların gücünü benimseyin ve React geliştirme becerilerinizi yükseltin!

React Özel Hook'lar: Yeniden Kullanılabilirlik için Bileşen Mantığını Çıkarma | MLOG