React Hookları — bu nədir, əsas hooklar və istifadə qaydaları

Müəllif: IT Sectr Dərc olunub: 2026-07-04 Oxuma vaxtı: 10 dəq

React Hookları — siniflər yazmadan funksional komponentlərdə vəziyyət, effektlər, kontekst və React-in digər imkanlarından istifadə etməyə imkan verən funksiyalardır. React 16.8-də təqdim edilən hooklar, HOC və render props kimi mürəkkəb naxışları əvəz edərək proqramlaşdırmaya yanaşmanı köklü şəkildə dəyişdi. React, 2024-ə görə, komponentin idarə edilməsinin bütün ssenarilərini əhatə edən 15 daxili hook var.

Başlıca

  • Hooklar — extends Component olmadan React imkanlarını funksional komponentlərə qoşmaq üçün funksiyalar.
  • useState — vəziyyəti idarə etmək üçün əsas hook, dəyər və setter qaytarır.
  • useEffect — yan təsirlər üçün: API sorğuları, abunəliklər, taymerlər, DOM manipulyasiyaları.
  • useContext — Consumer örtükləri və static contextType olmadan React kontekstinə giriş üçün.
  • Hook qaydaları — yalnız yuxarı səviyyədə və yalnız funksional komponentlər və ya xüsusi hooklar daxilində çağırılmalıdır.

React Hookları nədir?

React Hookları — siniflər yaratmadan çərçivənin daxili mexanizmlərinə „qoşulmağa” imkan verən React-in daxili funksiyalar toplusudur. React 16.8-dən əvvəl funksional komponentlər yalnız props qəbul edə və JSX qaytara bilirdi — istənilən mürəkkəb məntiq sinif komponenti tələb edirdi.

Sinif komponentlərinin problemi — əlaqəli məntiqin ayrılması. Bir varlığa aid kod (məsələn, WebSocket abunəliyi) məcburi şəkildə componentDidMount, componentDidUpdate və componentWillUnmount arasında bölünürdü. Hooklar bunu həll edir: bütün məntiq bir useEffect-də qruplaşdırılır.

Ikinci problem — məntiqin təkrar istifadəsi. Sinif komponentləri arasında vəziyyət məntiqini təkrar istifadə etmək üçün HOC (yüksək səviyyəli komponentlər) və ya render props tətbiq etmək lazım idi — hər iki naxış komponent ağacında əlavə iç-içəlik yaradırdı. Xüsusi hooklar bu problemi iç-içəlik olmadan həll edir.

useState — vəziyyətin idarə edilməsi

useState — ən əsas hook. Ilkin dəyər qəbul edir və kortej qaytarır: cari dəyər və onu yeniləmək üçün funksiya. Siniflərdəki this.setState-dən fərqli olaraq, useState obyektləri birləşdirmir — yeni vəziyyət müəyyən useState çağırışı üçün əvvəlki vəziyyəti tamamilə əvəz edir.

js
import React, { useState } from 'react';

function Form() {
  const [text, setText] = useState('');
  const [submitting, setSubmitting] = useState(false);

  async function handleSubmit() {
    setSubmitting(true);
    await fetch('/api/submit', {
      method: 'POST',
      body: JSON.stringify({ text })
    });
    setSubmitting(false);
  }

  return (
    <div>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <button onClick={handleSubmit}
        disabled={submitting}>
        {submitting ? 'Saving...' : 'Submit'}
      </button>
    </div>
  );
}

setState-in funksional forması

useState-in setteri əvvəlki dəyəri alan və yenisini qaytaran funksiya qəbul edə bilər. Funksional forma yeni vəziyyət əvvəlkindən hesablandıqda və setState-in toplu çağırışları mümkün olduqda məcburidir — hər çağırış aktual əvvəlki dəyəri alacaq.

useEffect — yan təsirlər və həyat dövri

useEffect — funksional komponentlərdə yan təsirləri yerinə yetirmək üçün hook. Iki arqument qəbul edir: effekt funksiyası və asılılıq massivi. React effekti hər renderdən sonra yerinə yetirir, lakin asılılıqlar göstərildikdə — yalnız onlardan hər hansı biri dəyişdikdə.

Boş asılılıq massivi [] effektin ilk renderdən sonra bir dəfə yerinə yetirildiyini bildirir (componentDidMount-un analoqu). Effektdən funksiya qaytarmaq təmizləmədir (cleanup), bu, komponent silinəndə (componentWillUnmount-un analoqu) və effekt yenidən yerinə yetirilməzdən əvvəl işləyir.

js
import React, { useState, useEffect } from 'react';

function ChatRoom({ roomId }) {
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    const socket = new WebSocket(`wss://chat/${roomId}`);

    socket.onmessage = (event) => {
      setMessages(prev => [...prev, JSON.parse(event.data)]);
    };

    // Cleanup - soketi bağla
    return () => socket.close();
  }, [roomId]);

  return <ul>
    {messages.map((msg, i) =>
      <li key={i}>{msg.text}</li>
    )}
  </ul>;
}

useEffect-in asılılıqları — effektlə xarici dünya arasında yeganə əlaqədir. Effektdə props və ya vəziyyətdən dəyişən istifadə edilirsə, o, asılılıq massivində olmalıdır. Bu qaydaya məhəl qoymamaq köhnəlmiş məlumatlarla (stale closure) bağlı səhvlərin mənbəyidir.

useContext — kontekstə giriş

useContext — kontekst dəyərini oxumaq üçün hook. React.createContext ilə yaradılmış kontekst obyektini qəbul edir və cari dəyəri qaytarır. Kontekst dəyişərsə, komponent avtomatik olaraq yeni dəyərlə yenidən render edilir.

useContext yaranana qədər funksional komponentlərdə kontekstə giriş Context.Consumer-də örtük tələb edirdi, bu da iç-içəlik yaradırdı. useContext Consumer-ı tamamilə aradan qaldırır — hook-u funksional komponentin istənilən yerində çağırmaq kifayətdir.

js
import React, { createContext, useContext } from 'react';

const ThemeContext = createContext('açıq');

function ThemedButton() {
  const theme = useContext(ThemeContext);

  return <button
    className={`btn btn-${theme}`}
  >
    {theme === 'dark' ? 'moon' : '☀️'}
  </button>;
}

useContext Redux və ya qlobal vəziyyətin əvəzi deyil. React kontekstdən nadir dəyişən dəyərlər üçün istifadə etməyi tövsiyə edir — mövzu, dil, icazə. Tez-tez yenilənən məlumatlar üçün hər yenidən render kontekstin bütün istehlakçılarını yenidən hesablayacaq, bu da performansı aşağı sala bilər.

useReducer — mürəkkəb vəziyyət məntiqi

useReducer — mürəkkəb yeniləmə məntiqi olan vəziyyətlər üçün useState-ə alternativdir. Reducer funksiyası və ilkin vəziyyət qəbul edir, cari vəziyyət və dispatch funksiyası qaytarır. Reducer cari vəziyyət və aksiyanı qəbul edir, yeni vəziyyət qaytarır — yan təsirləri olmayan təmiz funksiya.

useReducer xüsusilə bir neçə aksiya (set, reset, increment, addItem) bir vəziyyəti idarə etdikdə faydalıdır. Müxtəlif setterlərlə bir neçə useState əvəzinə — aydın aksiya tipləri ilə bir reducer. Bu, məntiqi proqnozlaşdırıla bilən və asanlıqla test edilə bilən edir.

js
import React, { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { ...state, count: state.count + 1 };
    case 'setStep':
      return { ...state, step: action.step };
    case 'reset':
      return { count: 0, step: 1 };
    default:
      throw new Error('Unknown action: ' + action.type);
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, {
    count: 0,
    step: 1
  });

  return (
    <>
      <p>Count: {state.count}</p>
      <button
        onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button
        onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </>
  );
}

useRef, useMemo, useCallback — optimallaşdırma

useRef renderlər arasında qorunan dəyişik obyekt yaradır. current-in dəyişməsi yenidən renderə səbəb olmur. Əsas tətbiqi — DOM elementlərinə giriş və dəyişik dəyərlərin saxlanması (taymerlər, əvvəlki dəyərlər, kitabxana nüsxələri).

useMemo funksiyanın nəticəsini yadda saxlayır. Dəyəri yalnız asılılıqlardan biri dəyişdikdə yenidən hesablayır. Bahalı hesablamalar üçün istifadə edin — böyük massivlərin filtrasiyası, sıralanması, məlumatların formatlaşdırılması. useCallback — funksiyaların yadda saxlanması üçün useMemo-nun xüsusi halı.

js
import React, { useRef, useMemo, useCallback } from 'react';

function SearchPage({ items, query, onItemSelect }) {
  const inputRef = useRef(null);

  // Quraşdırarkən avtofokus
  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  // Filtrə edilmiş nəticəni yadda saxla
  const filtered = useMemo(() => {
    return items.filter(item =>
      item.name.toLowerCase()
        .includes(query.toLowerCase())
    );
  }, [items, query]);

  // Callback-i yadda saxla
  const handleSelect = useCallback((id) => {
    onItemSelect(id);
  }, [onItemSelect]);

  return (
    <div>
      <input ref={inputRef}
        value={query}
        onChange={e => setQuery(e.target.value)}
      />
      <ul>
        {filtered.map(item =>
          <li key={item.id}>
            <button
              onClick={() => handleSelect(item.id)}>
              {item.name}
            </button>
          </li>
        )}
      </ul>
    </div>
  );
}

Vacib qayda: useRef, useMemo və useCallback — optimallaşdırma alətləridir, məcburi konstruksiyalar deyil. Hər şeyi useMemo ilə örtməyin — əvvəlcə performansı ölçün. Vaxtından əvvəl optimallaşdırma kodu çətinləşdirir. React komponentləri tez render edir; useMemo yalnız hesablamalar həqiqətən bahalı olduqda lazımdır (O(n²) və yuxarı).

Hook qaydaları və tez-tez edilən səhvlər

React hooklar üçün iki sərt qayda təqdim etdi. Birinci: hookları yalnız yuxarı səviyyədə çağırın — şərtlərin, dövrlərin və ya iç-içə funksiyaların daxilində deyil. Ikinci: hookları yalnız React funksional komponentlərindən və ya xüsusi hooklardan çağırın. ESLint-plugin eslint-plugin-react-hooks avtomatik olaraq hər iki qaydanı yoxlayır.

Ən tez-tez edilən səhv — hookların çağırılma ardıcıllığının pozulması. React renderlər arasında hookların çağırılma ardıcıllığına etibar edir. Hook şərt daxilindədirsə və renderlərdən birində çağırılmayıbsa, bütün sonrakı hooklar sürüşür — bu da səhvlərə səbəb olur.

SəhvNə baş verirHəlli
Şərtdə hookHookların sırası pozulurŞərtin məntiqini hookun içinə köçürün
Stale closureEffekt köhnə dəyərdən istifadə edirBütün asılılıqları massivə əlavə edin
Sonsuz dövrAsılılıqları olmayan useEffect vəziyyəti dəyişirAsılılıqları göstərin və ya useReducer istifadə edin
Renderdə ref-in dəyişdirilməsiFunksiya gövdəsində yan təsirMutasiyaları useEffect-ə köçürün

Ikinci tez-tez edilən səhv — useEffect-də stale closure. Effektdə asılılıqlarda göstərilməyən dəyişən istifadə edilirsə, effekt bağlanma anındakı dəyəri „tutur”. Həlli — istifadə olunan bütün dəyişənləri həmişə asılılıq massivinə daxil edin. Asılılıqlar çox olarsa, effekti bir neçə hissəyə bölmək olar.

Tez-tez verilən suallar

Niyə hookları şərtlərdə çağırmaq olmaz?

React hookların çağırılma ardıcıllığına etibar edir renderlər arasında. Hook şərt daxilində çağırılıbsa və renderlərdən birində işləməyibsə, bütün sonrakı hooklar „sürüşür” — onların vəziyyəti qarışır. ESLint qaydası hooks/exhaustive-deps bu barədə xəbərdarlıq edir.

useEffect və useLayoutEffect arasındakı fərq nədir?

useLayoutEffect sinxrondur və brauzer dəyişiklikləri çəkməzdən əvvəl yerinə yetirilir. useEffect asinxrondur — çɘkimdən sonra. useLayoutEffect yalnız istifadəçi dəyişiklikləri görməzdən əvvəl DOM-u ölçmək və ya dəyişmək lazım olduqda istifadə edin (popover mövqeyi, scroll restoration).

Komponent silinərkən fetch sorğusunu necə ləğv etməli?

useEffect daxilində AbortController istifadə edin. Controller yaradın, signal-ı fetch-ə ötürün və cleanup funksiyasında controller.abort() çağırın. Köhnə brauzerlər üçün cancelled bayrağı uyğundur: return () => { cancelled = true; } setState-dən əvvəl yoxlama ilə.

Xüsusi hook nədir və onu nə vaxt yaratmalı?

Xüsusi hook — use prefiksi ilə JavaScript funksiyası, daxili hooklardan istifadə edir. Eyni hook məntiqi iki və ya daha çox komponentdə təkrarlananda yaradın. Nümunələr: useDebounce, useLocalStorage, useMediaQuery. Xüsusi hooklar HOC və render props-u əvəz edir.

Niyə useEffect Strict Mode-da iki dəfə işləyir?

Strict Mode-da React təmizlənməmiş effektlərlə bağlı səhvləri tapmaq üçün tərtibat rejimində qəsdən komponenti iki dəfə mont edir və silir. Cleanup düzgün yazılıbsa, ikiqat çağırış problem yaratmır. İstehsal rejimində bu baş vermir.

Nəticə

  • React Hookları — sinifləri əvəz edərək funksional komponentlərdə vəziyyət, effektlər və kontekstdən istifadə etmək üçün funksiyalar.
  • useState — təhlükəsiz yeniləmələr üçün funksional setter ilə lokal vəziyyət üçün əsas hook.
  • useEffect — asılılıq massivi və cleanup funksiyası ilə yan təsirlər üçün universal hook.
  • useContext — Consumer örtükləri və əlavə iç-içəlik olmadan React kontekstinə birbaşa giriş.
  • useReducer — aksiya tipləri ilə mürəkkəb vəziyyət məntiqi üçün, bir komponent çərçivəsində Redux alternativi.
  • useRef, useMemo, useCallback — optimallaşdırma alətləri: DOM istinadları, dəyərlərin və callbacklərin yadda saxlanması.
  • Yuxarı səviyyə qaydası — hookları şərtlər, dövrlər və iç-içə funksiyalar xaricində çağırmaq üçün ciddi məhdudiyyət.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun