useRef — DOM ga murojaat, focus, scroll
Muammo: ba'zan DOM element kerak
React da odatda DOM ga to'g'ridan-to'g'ri tegmaysiz — state va props orqali boshqarasiz. Lekin ba'zi ishlar uchun haqiqiy DOM element kerak bo'ladi:
- Input ga focus berish
- Video ni play/pause qilish
- Elementning o'lchamini o'lchash
- Scroll pozitsiyasini boshqarish
Bularni state bilan qilib bo'lmaydi. useRef — DOM elementga to'g'ridan-to'g'ri murojaat qilish uchun.
useRef qanday ishlaydi?
import { useRef } from 'react';
function Forma() {
const inputRef = useRef(null);
function focusQilish() {
inputRef.current.focus(); // DOM elementga murojaat
}
return (
<div>
<input ref={inputRef} placeholder="Ism kiriting" />
<button onClick={focusQilish}>Focusga ol</button>
</div>
);
}
useRef(null) → { current: null }
│
JSX render bo'lganda │
▼
{ current: <input> } ← haqiqiy DOM element
ref={inputRef} — React bu elementni inputRef.current ga saqlaydi. Komponent chizilgandan keyin inputRef.current — haqiqiy <input> DOM elementi.
Amaliy misollar
Sahifa ochilganda input ga focus
function QidiruvSahifasi() {
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus(); // sahifa ochilganda darhol focus
}, []);
return <input ref={inputRef} placeholder="Qidirish..." />;
}
Video boshqarish
function VideoPlayer() {
const videoRef = useRef(null);
const [ishlayapti, setIshlayapti] = useState(false);
function togglePlay() {
if (ishlayapti) {
videoRef.current.pause();
} else {
videoRef.current.play();
}
setIshlayapti(!ishlayapti);
}
return (
<div>
<video ref={videoRef} src="/video.mp4" />
<button onClick={togglePlay}>
{ishlayapti ? 'Pauza' : 'Play'}
</button>
</div>
);
}
Xabar yuborilganda pastga scroll
function Chat() {
const [xabarlar, setXabarlar] = useState([]);
const pastRef = useRef(null);
useEffect(() => {
// yangi xabar kelganda pastga scroll
pastRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [xabarlar]);
return (
<div className="chat">
{xabarlar.map((x, i) => <p key={i}>{x}</p>)}
<div ref={pastRef} /> {/* eng pastdagi element */}
</div>
);
}
Tez-tez uchraydigan xatolar
ref.current ni render vaqtida ishlatish:
function Komponent() {
const ref = useRef(null);
// ❌ Xato — render vaqtida DOM hali tayyor emas
console.log(ref.current.offsetWidth);
// ✅ To'g'ri — useEffect ichida, DOM tayyor bo'lgandan keyin
useEffect(() => {
console.log(ref.current.offsetWidth);
}, []);
return <div ref={ref}>...</div>;
}
Shartli render bilan ref:
function Komponent({ korsatilsinmi }) {
const ref = useRef(null);
useEffect(() => {
// ❌ korsatilsinmi=false bo'lsa ref.current = null
ref.current.focus(); // xato!
// ✅ Avval tekshiring
ref.current?.focus();
}, []);
return korsatilsinmi ? <input ref={ref} /> : null;
}
Xulosa
const ref = useRef(null);
│
└── { current: null }
│
JSX render keyin
│
▼
{ current: <DOMElement> }
useRef — DOM elementga to'g'ridan-to'g'ri murojaat. Focus, scroll, media boshqarish uchun.
ref={...}JSX elementga beriladiref.current— haqiqiy DOM element- Faqat
useEffectichida yoki event handler da ishlating ?.optional chaining — element yo'q bo'lishi mumkin bo'lsa
Keyingi dars
14-dars: useRef — re-render bo'lmasdan qiymat saqlash, useState farqi