useNavigate — dasturiy navigatsiya

~10 daq · React · Routing

Muammodan boshlaylik

Foydalanuvchi kirish (login) formasini to'ldirdi va "Kirish" tugmasini bosdi. Server javob qaytardi: kirish muvaffaqiyatli. Endi nima qilasiz?

<Link> bilan sahifani almashtirish mumkin emas — <Link> faqat bosish uchun. Kod ichida, ya'ni onSubmit da navigatsiya qilish kerak.

Yoki boshqa holat: foydalanuvchi login qilmagan bo'lsa — avtomatik /kirish sahifasiga yo'naltirish kerak. Bu ham kod ichida bo'lishi kerak.

<Link> bu holatlar uchun emas. Buning uchun useNavigate hook i bor.


useNavigate nima?

useNavigate — kod orqali boshqa sahifaga o'tish imkonini beruvchi React Router hook i.

<Link> foydalanuvchi bosganida ishlaydi. useNavigate esa siz xohlagan istalgan vaqtda ishlaydi — forma yuborilganda, timeout o'tganda, shartga qarab, istalgan joyda.

Hayotiy o'xshatma: <Link> — yo'l ko'rsatuvchi belgi. Ko'rasiz va borasiz. useNavigate esa taksist — siz "qaerga" desangiz, u o'sha yerga olib boradi. Kerak bo'lganda, kerak bo'lgan vaqtda.


Asosiy ishlatilish

import { useNavigate } from 'react-router-dom';

function KirishForma() {
  const navigate = useNavigate(); // ← hook dan funksiya olamiz

  function yuborish(e) {
    e.preventDefault();
    // ... server bilan ishlash ...

    navigate('/bosh-sahifa'); // ← navigatsiya
  }

  return (
    <form onSubmit={yuborish}>
      <input type="email" placeholder="Email" />
      <input type="password" placeholder="Parol" />
      <button type="submit">Kirish</button>
    </form>
  );
}

navigate('/bosh-sahifa') — sahifani yangilamaydi, faqat URL ni o'zgartiradi va mos komponentni ko'rsatadi.


navigate — turli xil ishlatilishi

Manzilga o'tish

navigate('/mahsulotlar');         // /mahsulotlar ga o'tish
navigate('/mahsulot/42');         // dinamik manzilga
navigate('/qidiruv?kalit=telefon'); // query bilan

Orqaga va oldinga

navigate(-1); // orqaga — brauzer "←" tugmasi kabi
navigate(1);  // oldinga — brauzer "→" tugmasi kabi
navigate(-2); // ikki qadam orqaga

Bu raqamlar brauzer tarixidagi qadamlarni bildiradi.

replace — tarixni almashtirish

navigate('/bosh-sahifa', { replace: true });

Oddiy navigate tarixga yangi yozuv qo'shadi — foydalanuvchi "orqaga" bossa oldingi sahifaga qaytadi.

replace: true bilan esa joriy yozuv almashtiriladi — "orqaga" tugmasi undan oldingi sahifaga olib boradi.

Qachon kerak? Login sahifasidan keyin. Foydalanuvchi kirdi, /bosh-sahifa ga yo'naltirildi. Endi "orqaga" bossa — login sahifasiga qaytmasligi kerak (u allaqachon kirgan).

// Login muvaffaqiyatli bo'lgandan keyin
navigate('/bosh-sahifa', { replace: true });
// Endi "orqaga" tugmasi login sahifasini ko'rsatmaydi

state — qo'shimcha ma'lumot uzatish

URL da ko'rinmaydigan ma'lumotni keyingi sahifaga uzatish:

navigate('/buyurtma', {
  state: {
    mahsulotId: 42,
    miqdor: 3,
  },
});

Keyingi sahifada useLocation bilan olinadi:

import { useLocation } from 'react-router-dom';

function Buyurtma() {
  const { state } = useLocation();
  console.log(state?.mahsulotId); // 42
  console.log(state?.miqdor);     // 3
}

Amaliy misollar

1. Login forma — muvaffaqiyatdan keyin yo'naltirish

import { useNavigate } from 'react-router-dom';
import { useState } from 'react';

function KirishSahifasi() {
  const navigate = useNavigate();
  const [xato, setXato] = useState('');

  async function yuborish(e) {
    e.preventDefault();
    const malumot = new FormData(e.target);

    try {
      await login({
        email: malumot.get('email'),
        parol: malumot.get('parol'),
      });

      navigate('/bosh-sahifa', { replace: true }); // ← tarixni almashtir
    } catch {
      setXato('Email yoki parol noto\'g\'ri');
    }
  }

  return (
    <form onSubmit={yuborish}>
      <input name="email" type="email" />
      <input name="parol" type="password" />
      {xato && <p style={{ color: 'red' }}>{xato}</p>}
      <button type="submit">Kirish</button>
    </form>
  );
}

2. Foydalanuvchi kirish qilmagan — himoyalangan sahifa

import { useNavigate } from 'react-router-dom';
import { useEffect } from 'react';

function HimoyalanganSahifa() {
  const navigate = useNavigate();
  const { foydalanuvchi } = useAuth(); // sizning auth hook ingiz

  useEffect(() => {
    if (!foydalanuvchi) {
      navigate('/kirish', { replace: true }); // ← kirish sahifasiga
    }
  }, [foydalanuvchi, navigate]);

  if (!foydalanuvchi) return null;

  return <h1>Faqat kirgan foydalanuvchilar uchun</h1>;
}

3. Forma yuborilgandan keyin — orqaga qaytish

function MahsulotTahrir() {
  const navigate = useNavigate();

  async function saqlash(e) {
    e.preventDefault();
    await mahsulotniSaqlash(formaMalumotlari);

    navigate(-1); // ← oldingi sahifaga qaytish
  }

  return (
    <form onSubmit={saqlash}>
      {/* forma maydonlari */}
      <button type="submit">Saqlash</button>
      <button type="button" onClick={() => navigate(-1)}>
        Bekor qilish
      </button>
    </form>
  );
}

4. Timeout — avtomatik yo'naltirish

import { useNavigate } from 'react-router-dom';
import { useEffect } from 'react';

function MuvaffaqiyatSahifasi() {
  const navigate = useNavigate();

  useEffect(() => {
    const taymer = setTimeout(() => {
      navigate('/bosh-sahifa'); // ← 3 soniyadan keyin
    }, 3000);

    return () => clearTimeout(taymer); // ← tozalash
  }, [navigate]);

  return <h1>Buyurtma qabul qilindi! 3 soniyada bosh sahifaga o'tasiz...</h1>;
}

navigate ni dependency array ga qo'shish kerakmi?

Ha — lekin xavotir olish shart emas. React Router navigate funksiyasini har render da yangi yaratmaydi — u barqaror (stable). useEffect dependency array ga qo'shilishi eslint uchun to'g'ri, lekin amalda hech narsa o'zgarmaydi.

useEffect(() => {
  if (!foydalanuvchi) {
    navigate('/kirish');
  }
}, [foydalanuvchi, navigate]); // ← navigate qo'shildi — to'g'ri

Tez-tez uchraydigan xatolar

1. navigate ni render vaqtida chaqirish

// ❌ Xato — render vaqtida navigatsiya
function Komponent() {
  const navigate = useNavigate();

  if (!foydalanuvchi) {
    navigate('/kirish'); // ← render ichida!
  }

  return <div>...</div>;
}
// ✅ To'g'ri — useEffect ichida
function Komponent() {
  const navigate = useNavigate();

  useEffect(() => {
    if (!foydalanuvchi) {
      navigate('/kirish');
    }
  }, [foydalanuvchi, navigate]);

  return <div>...</div>;
}

Sababi: Render vaqtida yon ta'sir (side effect) yaratish React qoidalariga zid. Render sof funksiya bo'lishi kerak. navigate chaqirish — yon ta'sir, shuning uchun useEffect ichida.


2. Login dan keyin replace unutish

// ❌ Xato — replace yo'q
navigate('/bosh-sahifa');

// ✅ To'g'ri — replace bilan
navigate('/bosh-sahifa', { replace: true });

Sababi: replace siz foydalanuvchi kirdi, /bosh-sahifa da. "Orqaga" bossa — /kirish sahifasiga qaytadi. Kirgan odamga login sahifasi ko'rsatilishi mantiqsiz. replace: true bilan login tarixi o'chirilib, /bosh-sahifa yangi boshlang'ich bo'ladi.


3. useNavigate ni komponent tashqarisida chaqirish

// ❌ Xato — hook komponent tashqarisida
const navigate = useNavigate();

function yuborish() {
  navigate('/bosh-sahifa');
}
// ✅ To'g'ri — hook komponent ichida
function Forma() {
  const navigate = useNavigate(); // ← komponent ichida

  function yuborish() {
    navigate('/bosh-sahifa');
  }

  return <button onClick={yuborish}>Yuborish</button>;
}

Sababi: Barcha React hook lari faqat komponent funksiyasi ichida chaqirilishi shart. Bu React ning asosiy qoidasi.


4. Har safar navigate chaqirilganda cheksiz render

// ❌ Xato — navigate dependency yo'q, lekin navigate doim yangilanadi deb o'ylash
useEffect(() => {
  navigate('/kirish');
}); // ← dependency array yo'q! Har render da chaqiriladi
// ✅ To'g'ri — dependency array bor
useEffect(() => {
  if (!foydalanuvchi) {
    navigate('/kirish');
  }
}, [foydalanuvchi, navigate]); // ← faqat foydalanuvchi o'zgarganda

Sababi: Dependency array bo'lmasa, useEffect har render da ishlaydi. navigate → render → navigate → cheksiz sikl.


Xulosa

  • useNavigate — kod orqali navigatsiya uchun hook
  • navigate('/manzil') — ko'rsatilgan sahifaga o'tish
  • navigate(-1) — orqaga, navigate(1) — oldinga
  • navigate('/manzil', { replace: true }) — tarixni almashtirish (login uchun)
  • navigate('/manzil', { state: {...} }) — ma'lumot uzatish
  • Render vaqtida emas, useEffect yoki event handler ichida chaqiriladi

Keyingi dars: 43-dars: useParams — URL parametrlarni olish