useRef Hook
useRef Hook — DOM-ի հետ աշխատանք և արժեքների պահպանում առանց rerender-ի
useRef hook-ը React-ում ունի երկու հիմնական դեր․
useRef-ը վերադարձնում է օբյեկտ այս տեսքով՝
{ current: ... }Այդ current հատկության մեջ React-ը պահում է reference-ը։
const ref = useRef(initialValue);
Սա ամենահայտնի և տարածված օրինակը է՝ ref-ի միջոցով input-ին մուտք գործելու։
import React, { useRef } from 'react';
export default function InputFocus() {
const inputRef = useRef(null);
function handleFocus() {
inputRef.current.focus();
}
return (
<div>
<input ref={inputRef} placeholder="Գրիր ինչ-որ բան..." />
<button onClick={handleFocus}>Ֆոկուսացնել</button>
</div>
);
}
Այս օրինակում `inputRef.current`-ը հղվում է input DOM էլեմենտին։ Սեղմելով կոճակը՝ մենք programmatically ֆոկուսացնում ենք input-ը։
Եթե ցանկանում ես պահել փոփոխական, որը չի կորի rerender-ների ժամանակ, բայց նաև rerender չի առաջացնի, օգտագործիր ref։ Սա շատ օգտակար է՝ timers, previous values կամ metrics պահելու համար։
import React, { useRef, useState, useEffect } from 'react';
export default function RenderCounter() {
const [count, setCount] = useState(0);
const renders = useRef(0);
useEffect(() => {
renders.current = renders.current + 1;
});
return (
<div>
<p>Count: {count}</p>
<p>Render count: {renders.current}</p>
<button onClick={() => setCount(prev => prev + 1)}>Ավելացնել</button>
</div>
);
}
Այս օրինակում `renders.current` արժեքը պահպանում է render-ների քանակը, բայց rerender չի առաջացնում՝ նույնիսկ երբ փոփոխվում է։ Եթե նույն բանն անեինք state-ով, դա կբերեր անվերջ ռենդերին։
React-ը rerender է անում միայն այն դեպքում, երբ state կամ props են փոխվում։ Ref-ը հատուկ ստեղծված է “մշտական պահոց” լինելու համար՝ առանց rerender trigger անելու։ React-ը պարզապես հիշում է այդ արժեքը կոմպոնենտի ողջ կյանքի ընթացքում։
Սա պրոֆեսիոնալ օրինակ է՝ երբ ուզում ես իմանալ, թե ինչ էր state-ի նախորդ արժեքը։
import React, { useState, useEffect, useRef } from 'react';
export default function PreviousValue() {
const [name, setName] = useState('');
const prevName = useRef('');
useEffect(() => {
prevName.current = name; // պահպանենք նախորդ արժեքը
}, [name]);
return (
<div>
<input value={name} onChange={e => setName(e.target.value)} />
<p>Ընթացիկ անունը՝ {name}</p>
<p>Նախորդ անունը՝ {prevName.current}</p>
</div>
);
}
Ամեն անգամ, երբ name-ը փոխվում է, մենք պահպանում ենք նախորդ արժեքը ref-ում։ Սա շատ հաճախ օգտագործվում է form validation-ի, comparison-ի կամ animations-ի ժամանակ։
Եթե setInterval-ը ստեղծվում է effect-ի մեջ, ref-ը կարող է օգնել պահպանել վերջին callback-ը՝ առանց նոր interval ստեղծելու ամեն render-ի ժամանակ։
import React, { useState, useEffect, useRef } from 'react';
export default function Timer() {
const [seconds, setSeconds] = useState(0);
const intervalRef = useRef(null);
useEffect(() => {
intervalRef.current = setInterval(() => {
setSeconds(s => s + 1);
}, 1000);
return () => clearInterval(intervalRef.current);
}, []);
return (
<div>
<p>Անցած ժամանակ՝ {seconds} վայրկյան</p>
<button onClick={() => clearInterval(intervalRef.current)}>Դադարեցնել</button>
</div>
);
}
Ref-ը այստեղ պահում է interval-ի ID-ն, որպեսզի հեշտ լինի դադարեցնել այն, առանց state-ի փոփոխության։
| useState | useRef |
|---|---|
| Փոփոխությունը rerender է առաջացնում։ | Փոփոխությունը rerender չի առաջացնում։ |
| Պահպանում է տվյալը՝ render-ի համար։ | Պահպանում է տվյալը՝ կոմպոնենտի կյանքի ընթացքում։ |
| Օգտագործվում է UI-ի թարմացման համար։ | Օգտագործվում է DOM-ի կամ ներքին տվյալների համար։ |
Գրիր կոմպոնենտ, որը․
Օգտագործիր միայն մեկ hook՝ useRef՝ երեք նպատակի համար։