Ποια είναι τα hooks στο React;
sobes.tech AI
Απάντηση από AI
Στο React, από την έκδοση 16.8 και μετά, τα hooks παρέχουν στις λειτουργικές συνιστώσες τη δυνατότητα να διαχειρίζονται την κατάσταση και να χρησιμοποιούν κύκλους ζωής, που προηγουμένως ήταν διαθέσιμοι μόνο σε κλασικές συνιστώσες.
Ακολουθούν τα βασικά ενσωματωμένα hooks:
-
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 context. Δέχεται ένα αντικείμενο context που δημιουργείται με τοReact.createContext().// Παράδειγμα useContext import React, { useContext } from 'react'; const ThemeContext = React.createContext('light'); // Δημιουργία context function ThemedButton() { const theme = useContext(ThemeContext); // Χρήση context return ( <button className={theme}> Κουμπί με θέμα {theme} </button> ); } function App() { return ( <ThemedButton /> ); } -
useReducer: Μια εναλλακτική τουuseStateγια διαχείριση πιο πολύπλοκων καταστάσεων, που περιλαμβάνουν πολλαπλές υπο-τιμές ή όταν η επόμενη κατάσταση εξαρτάται από την προηγούμενη. Παρόμοιο με τους reducer στο 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 ( <> Count: {state.count} <button onClick={() => dispatch({ type: 'increment' })}>+</button> <button onClick={() => dispatch({ type: 'decrement' })}>-</button> </> ); } -
useCallback: Μνημονεύει μια συνάρτηση callback. Επιστρέφει μια μνημονευμένη έκδοση της callback, η οποία αλλάζει μόνο αν αλλάξει μια από τις εξαρτήσεις. Χρησιμοποιείται για την αποτροπή περιττών επανακατασκευών παιδικών συστατικών κατά τη μεταβίβαση callbacks.// Παράδειγμα 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('Το παιδικό συστατικό ανακατασκευάζεται'); // Θα ανακατασκευάζεται μόνο αν αλλάξει το 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: Επιτρέπει τη δημιουργία μιας μεταβλητής ref, η οποία διατηρείται καθ' όλη τη διάρκεια ζωής του συστατικού. Συχνά χρησιμοποιείται για πρόσβαση σε στοιχεία DOM ή αποθήκευση οποιασδήποτε μεταβλητής που δεν προκαλεί επανακατασκευή.// Παράδειγμα useRef import React, { useRef } from 'react'; function TextInputWithFocusButton() { const inputEl = useRef(null); // Δημιουργία ref const onButtonClick = () => { // current δείχνει το τοποθετημένο στοιχείο DOM inputEl.current.focus(); }; return ( <> <input ref={inputEl} type="text" /> // Σύνδεση ref <button onClick={onButtonClick}>Εστίαση στο πεδίο εισαγωγής</button> </> ); } -
useImperativeHandle: Ρυθμίζει τον περιγραφέα της στιγμιαίας κατάστασης που παρέχεται στον γονέα κατά τη χρήση τουref. Επιτρέπει στο παιδικό συστατικό να αποκαλύψει ορισμένες μεθόδους στον γονέα. Χρησιμοποιείται μαζί με τοforwardRef.// Παράδειγμα 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(); // Metoda από το παιδικό συστατικό }; return ( <div> <MyInput ref={inputRef} /> <button onClick={handleFocus}>Εστίαση μέσω Parent</button> </div> ); } -
useLayoutEffect: Παρόμοιο με τοuseEffect, αλλά εκτελείται συγχρονικά μετά από όλες τις μετατροπές DOM. Χρησιμοποιείται για ανάγνωση δεδομένων από το DOM ή εκτέλεση μετατροπών που πρέπει να γίνουν πριν από την ανανέωση της οθόνης από το πρόγραμμα περιήγησης. Μπορεί να μπλοκάρει το rendering.// Παράδειγμα useLayoutEffect import React, { useLayoutEffect, useRef } from 'react'; function Tooltip({ children, text }) { const ref = useRef(null); useLayoutEffect(() => { if (ref.current) { // Υπολογισμοί με βάση το DOM πριν από την ανανέωση const { top, height } = ref.current.getBoundingClientRect(); console.log(`Το στοιχείο βρίσκεται στο ${top} με ύψος ${height}`); } }, [children]); return ( <span ref={ref} title={text}> {children} </span> ); } -
useDebugValue: Εμφανίζει μια προσαρμοσμένη ετικέτα για τα hooks στα React DevTools. Χρησιμοποιείται σε προσαρμοσμένα hooks για αποσφαλμάτωση.// Παράδειγμα useDebugValue import React, { useState, useDebugValue } from 'react'; function useFriendStatus(friendID) { const [isOnline, setIsOnline] = useState(null); // Εμφανίζει "Κατάσταση φίλου: Offline" ή "Κατάσταση φίλου: Online" στα DevTools useDebugValue(isOnline === true ? 'Online' : 'Offline'); // ... λογική για λήψη κατάστασης φίλου return isOnline; } function FriendListItem({ friend }) { const isOnline = useFriendStatus(friend.id); return ( <li style={{ color: isOnline ? 'πράσινο' : 'μαύρο' }}> {friend.name} - {isOnline ? 'Online' : 'Offline'} </li> ); }
Εκτός από τα ενσωματωμένα hooks, υπάρχουν και προσαρμοσμένα hooks (Custom Hooks). Αυτά είναι συναρτήσεις JavaScript που ξεκινούν με "use". Επιτρέπουν την επανάχρηση της λογικής κατάστασης μεταξύ των συστατικών. Ένα προσαρμοσμένο hook μπορεί να καλεί άλλα hooks.
// Παράδειγμα προσαρμοσμένου hook
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(); // Χρήση προσαρμοσμένου hook
return (
<p>Μέγεθος παραθύρου: {width}x{height}</p>
);
}
Είναι σημαντικό να ακολουθούνται οι κανόνες των hooks:
- Καλείτε τα hooks μόνο στην κορυφή του συστατικού React ή του προσαρμοσμένου hook. Μην τα καλείτε μέσα σε βρόχους, συνθήκες ή εσωτερικές συναρτήσεις.
- Καλείτε τα hooks μόνο από λειτουργικά συστατικά React ή προσαρμοσμένα hooks. Μην τα καλείτε από κανονικές JavaScript συναρτήσεις ή μεθόδους κλασικών συστατικών.