Ի՞նչ hook-եր կան React-ում։
sobes.tech AI
Պատասխան AI-ից
React- ում, սկսած 16.8 տարբերակից, հուկերը տրամադրում են ֆունկցիոնալ կոմպոնենտներին հնարավորություն կառավարել վիճակը և օգտագործել կյանքի ցիկլերը, որոնք նախկինում հասանելի էին միայն դասական կոմպոնենտներին:
Սրանք հիմնական ներքին հուկերն են:
-
useState: թույլ է տալիս ավելացնել ներքին վիճակ ֆունկցիոնալ կոմպոնենտին: վերադարձնում է զույգ՝ ընթացիկ վիճակ և ֆունկցիա դրա թարմացման համար:// useState օրինակ import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); // սկզբնական արժեք 0 return ( <div> <p>Դուք սեղմել եք {count} անգամ</p> <button onClick={() => setCount(count + 1)}> Սեղմեք ինձ </button> </div> ); } -
useEffect: թույլ է տալիս կատարել կողմնակի ազդեցություններ ֆունկցիոնալ կոմպոնենտներում: նման է դասի կյանքի ցիկլի մեթոդներին (componentDidMount,componentDidUpdate,componentWillUnmount):// useEffect օրինակ import React, { useState, useEffect } from 'react'; function Example() { const [count, setCount] = useState(0); // կատարվում է յուրաքանչյուր ռենդերի հետո useEffect(() => { document.title = `Դուք սեղմել եք ${count} անգամ`; }); // կատարվում է միայն առաջին ռենդերի ժամանակ (ապակող կախվածությունների զանգված) useEffect(() => { console.log('Կոմպոնենտը մոնտորյան է'); return () => { console.log('Կոմպոնենտը անմոնտորյան է'); // մաքրման ֆունկցիա }; }, []); // կատարվում է միայն count փոփոխության դեպքում useEffect(() => { console.log('Count փոխվել է:', count); }, [count]); return ( <div> <p>Դուք սեղմել եք {count} անգամ</p> <button onClick={() => setCount(count + 1)}> Սեղմեք ինձ </button> </div> ); } -
useContext: թույլ է տալիս բաժանորդագրվել React կոնտեքստի փոփոխություններին: ընդունում է կոնտեքստի օբյեկտ, որը ստեղծվել էReact.createContext()-ով:// useContext օրինակ import React, { useContext } from 'react'; const ThemeContext = React.createContext('light'); // կոնտեքստի ստեղծում function ThemedButton() { const theme = useContext(ThemeContext); // կոնտեքստի օգտագործում return ( <button className={theme}> Կոճակ թեմայով {theme} </button> ); } function App() { return ( <ThemedButton /> ); } -
useReducer:useState-ի ալտերնատիվ է ավելի բարդ վիճակների կառավարման համար, որոնք ներառում են մի քանի ենթավիճակներ կամ երբ հաջորդ վիճակը կախված է նախորդից: նման է Redux-ի ռեդյուրսներին:// useReducer օրինակ import React, { 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 Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <> <p>Հաշվիչը՝ {state.count}</p> <button onClick={() => dispatch({ type: 'increment' })}>+</button> <button onClick={() => dispatch({ type: 'decrement' })}>-</button> </> ); } -
useCallback: մեմոիզացնում է callback ֆունկցիան: վերադարձնում է մեմոիզացված տարբերակը, որը փոխվում է միայն կախվածություններից մեկի փոփոխության դեպքում: օգտակար է անպատճառ կրկնվող ռենդերներից խուսափելու համար, երբ փոխանցվում է երեխաների կոմպոնենտներին:// useCallback օրինակ import React, { useState, useCallback } from 'react'; function Parent({ addTodo }) { const [count, setCount] = useState(0); const handleAddTodo = useCallback(() => { addTodo(); }, [addTodo]); // կախվածություն addTodo-ից return ( <> <button onClick={() => setCount(count + 1)}> Հաշվիչը մեծացնել </button> <Child onAddItem={handleAddTodo} /> </> ); } function Child({ onAddItem }) { console.log('Child ռենդեր է'); // միայն այն ժամանակ, երբ փոխվում է onAddItem return <button onClick={onAddItem}>Ավելացնել տարր</button>; } -
useMemo: մեմոիզացնում է արժեքը: վերադարձնում է մեմոիզացված արժեք, որը վերամշակվում է միայն կախվածություններից մեկի փոփոխության դեպքում: օգտակար է ծանր հաշվարկների համար:// useMemo օրինակ import React, { useMemo, useState } from 'react'; function expensiveCalculation(num) { console.log('Բարդ հաշվարկ կատարվում է...'); for (let i = 0; i < 1000000; i++) { num += 1; } return num; } function Example() { const [count, setCount] = useState(0); const [todos, setTodos] = useState([]); const calculation = useMemo(() => expensiveCalculation(count), [count]); // կախվածություն count-ից const addTodo = () => { setTodos(t => [...t, "Նոր Todo"]); }; return ( <div> <div> <h2>Իմ Todo-երը</h2> {todos.map((todo, index) => ( <p key={index}>{todo}</p> ))} <button onClick={addTodo}>Ավելացնել Todo</button> </div> <hr /> <div> Հաշվիչ: {count} <button onClick={() => setCount(c => c + 1)}>+</button> <h2>Բարդ հաշվարկ</h2> {calculation} </div> </div> ); } -
useRef: թույլ է տալիս ստեղծել մուտաբել ռեֆ, որը պահպանվում է ամբողջ կոմպոնենտի կյանքի ցիկլի ընթացքում: հաճախ օգտագործվում է DOM տարրին մուտք գործելու կամ ցանկացած մուտաբել արժեք պահելու համար, որը չի առաջացնում ռենդեր:// useRef օրինակ import React, { useRef } from 'react'; function TextInputWithFocusButton() { const inputEl = useRef(null); // ռեֆ ստեղծում const onButtonClick = () => { // current ցույց է տալիս մոնտորացված DOM տարրին inputEl.current.focus(); }; return ( <> <input ref={inputEl} type="text" /> // ռեֆ կապում է <button onClick={onButtonClick}>Ֆոկուս դնել մուտքային դաշտում</button> </> ); } -
useImperativeHandle: կարգավորում է օրինակային դիսկրիպտորը, որը մատչելի է ծնող կոմպոնենտինref-ի միջոցով: թույլ է տալիս երեխային բացահայտել որոշ մեթոդներ ծնողին:// useImperativeHandle օրինակ import React, { useRef, useImperativeHandle, forwardRef } from 'react'; const MyInput = forwardRef((props, ref) => { const inputRef = useRef(); useImperativeHandle(ref, () => ({ focusInput: () => { inputRef.current.focus(); } })); return <input ref={inputRef} {...props} />; }); function ParentComponent() { const inputRef = useRef(); const handleFocus = () => { inputRef.current.focusInput(); // երեխային մեթոդ կանչում }; return ( <div> <MyInput ref={inputRef} /> <button onClick={handleFocus}>Ֆոկուս տալ ծնողից</button> </div> ); } -
useLayoutEffect: նույն է, ինչuseEffect, բայց կատարվում է սինխրոն՝ բոլոր մուտացիաների հետո, նախքան բրաուզերի ռենդերը:// useLayoutEffect օրինակ import React, { useLayoutEffect, useRef } from 'react'; function Tooltip({ children, text }) { const ref = useRef(null); useLayoutEffect(() => { if (ref.current) { const { top, height } = ref.current.getBoundingClientRect(); console.log(`Էլեմենտը գտնվում է ${top} բարձրության վրա, բարձրությունը՝ ${height}`); } }, [children]); return ( <span ref={ref} title={text}> {children} </span> ); } -
useDebugValue: ցուցադրում է օգտագործողի նշում React DevTools-ում հուկի համար:// useDebugValue օրինակ import React, { useState, useDebugValue } from 'react'; function useFriendStatus(friendID) { const [isOnline, setIsOnline] = useState(null); useDebugValue(isOnline === true ? 'Առցանց' : 'Անցանց'); // ... ընկերոջ կարգավիճակի տրամադրելու լոգիկա return isOnline; } function FriendListItem({ friend }) { const isOnline = useFriendStatus(friend.id); return ( <li style={{ color: isOnline ? 'կանաչ' : 'սև' }}> {friend.name} - {isOnline ? 'Առցանց' : 'Անցանց'} </li> ); }
Բացի ներքին հուկերից, կան նաև օգտագործողի հուկեր (Custom Hooks): դրանք JavaScript ֆունկցիաներ են, որոնց անունները սկսվում են "use":
// Օգտագործողի հուկի օրինակ
import { useState, useEffect } from 'react';
function useWindowSize() {
const [size, setSize] = useState([window.innerWidth, window.innerHeight]);
useEffect(() => {
const handleResize = () => {
setSize([window.innerWidth, window.innerHeight]);
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return size;
}
function MyComponent() {
const [width, height] = useWindowSize(); // օգտագործում է օգտվողի հուկը
return (
<p>Վահանակի չափը՝ {width}x{height}</p>
);
}
Կարևոր է հետևել հուկերի կանոններին:
- Հուկերը կանչել միայն React կոմպոնենտի վերևում կամ օգտագործողի հուկում: Չի կարելի կանչել ցիկլերում, պայմաններում կամ ներսի ֆունկցիաներում:
- Հուկերը կանչել միայն React ֆունկցիոնալ կոմպոնենտներից կամ օգտագործողի հուկներից: Չի կարելի կանչել սովորական JavaScript ֆունկցիաներից կամ դասական կոմպոնենտների մեթոդներից։