Ελληνικά

Μάθετε πώς να αξιοποιήσετε τα React custom hooks για να εξάγετε και να επαναχρησιμοποιήσετε τη λογική των components, βελτιώνοντας τη συντηρησιμότητα, τη δοκιμαστικότητα και τη συνολική αρχιτεκτονική της εφαρμογής.

React Custom Hooks: Εξαγωγή Λογικής Component για Επαναχρησιμοποίηση

Τα React hooks έχουν φέρει επανάσταση στον τρόπο που γράφουμε React components, προσφέροντας έναν πιο κομψό και αποτελεσματικό τρόπο διαχείρισης της κατάστασης και των παρενεργειών. Μεταξύ των διαφόρων διαθέσιμων hooks, τα custom hooks ξεχωρίζουν ως ένα ισχυρό εργαλείο για την εξαγωγή και την επαναχρησιμοποίηση της λογικής των components. Αυτό το άρθρο παρέχει έναν ολοκληρωμένο οδηγό για την κατανόηση και την εφαρμογή των React custom hooks, δίνοντάς σας τη δυνατότητα να δημιουργήσετε πιο συντηρήσιμες, δοκιμαστικές και επεκτάσιμες εφαρμογές.

Τι είναι τα React Custom Hooks;

Στην ουσία, ένα custom hook είναι μια συνάρτηση JavaScript της οποίας το όνομα ξεκινά με "use" και μπορεί να καλέσει άλλα hooks. Σας επιτρέπει να εξάγετε τη λογική των components σε επαναχρησιμοποιήσιμες συναρτήσεις, εξαλείφοντας έτσι την επανάληψη κώδικα και προωθώντας μια καθαρότερη δομή component. Σε αντίθεση με τα κανονικά React components, τα custom hooks δεν αποδίδουν κανένα UI. απλώς ενθυλακώνουν λογική.

Σκεφτείτε τα ως επαναχρησιμοποιήσιμες συναρτήσεις που μπορούν να έχουν πρόσβαση στην κατάσταση του React και στις λειτουργίες του κύκλου ζωής. Είναι ένας φανταστικός τρόπος για να μοιραστείτε τη λογική διαχείρισης κατάστασης μεταξύ διαφορετικών components χωρίς να καταφύγετε σε components υψηλότερης τάξης ή render props, τα οποία συχνά οδηγούν σε κώδικα που είναι δύσκολο να διαβαστεί και να συντηρηθεί.

Γιατί να χρησιμοποιήσετε Custom Hooks;

Τα οφέλη από τη χρήση custom hooks είναι πολλά:

Δημιουργία του πρώτου σας Custom Hook

Ας απεικονίσουμε τη δημιουργία και τη χρήση ενός custom hook με ένα πρακτικό παράδειγμα: ανάκτηση δεδομένων από ένα API.

Παράδειγμα: useFetch - Ένα Hook Ανάκτησης Δεδομένων

Φανταστείτε ότι χρειάζεται συχνά να ανακτήσετε δεδομένα από διαφορετικά API στην εφαρμογή σας React. Αντί να επαναλαμβάνετε τη λογική ανάκτησης σε κάθε component, μπορείτε να δημιουργήσετε ένα useFetch hook.


import { useState, useEffect } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const abortController = new AbortController();
    const signal = abortController.signal;

    const fetchData = async () => {
      setLoading(true);
      try {
        const response = await fetch(url, { signal: signal });
        if (!response.ok) {
          throw new Error(`HTTP error! Status: ${response.status}`);
        }
        const json = await response.json();
        setData(json);
        setError(null); // Clear any previous errors
      } catch (error) {
        if (error.name === 'AbortError') {
          console.log('Fetch aborted');
        } else {
          setError(error);
        }
        setData(null); // Clear any previous data
      } finally {
        setLoading(false);
      }
    };

    fetchData();

    return () => {
      abortController.abort(); // Cleanup function to abort the fetch on unmount or URL change
    };
  }, [url]); // Re-run effect when the URL changes

  return { data, loading, error };
}

export default useFetch;

Επεξήγηση:

Χρήση του useFetch Hook σε ένα Component

Τώρα, ας δούμε πώς να χρησιμοποιήσετε αυτό το custom hook σε ένα React component:


import React from 'react';
import useFetch from './useFetch';

function UserList() {
  const { data: users, loading, error } = useFetch('https://jsonplaceholder.typicode.com/users');

  if (loading) return <p>Loading users...</p>;
  if (error) return <p>Error: {error.message}</p>;
  if (!users) return <p>No users found.</p>;

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name} ({user.email})</li>
      ))}
    </ul>
  );
}

export default UserList;

Επεξήγηση:

Προηγμένα Μοτίβα Custom Hook

Πέρα από την απλή ανάκτηση δεδομένων, τα custom hooks μπορούν να χρησιμοποιηθούν για την ενθυλάκωση πιο σύνθετης λογικής. Ακολουθούν μερικά προηγμένα μοτίβα:

1. Διαχείριση Κατάστασης με useReducer

Για πιο σύνθετα σενάρια διαχείρισης κατάστασης, μπορείτε να συνδυάσετε custom hooks με useReducer. Αυτό σας επιτρέπει να διαχειρίζεστε τις μεταβάσεις κατάστασης με έναν πιο προβλέψιμο και οργανωμένο τρόπο.


import { 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 useCounter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  const increment = () => dispatch({ type: 'increment' });
  const decrement = () => dispatch({ type: 'decrement' });

  return { count: state.count, increment, decrement };
}

export default useCounter;

Χρήση:


import React from 'react';
import useCounter from './useCounter';

function Counter() {
  const { count, increment, decrement } = useCounter();

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

export default Counter;

2. Ενσωμάτωση Context με useContext

Τα Custom hooks μπορούν επίσης να χρησιμοποιηθούν για να απλοποιήσουν την πρόσβαση στο React Context. Αντί να χρησιμοποιείτε το useContext απευθείας στα components σας, μπορείτε να δημιουργήσετε ένα custom hook που ενθυλακώνει τη λογική πρόσβασης στο context.


import { useContext } from 'react';
import { ThemeContext } from './ThemeContext'; // Assuming you have a ThemeContext

function useTheme() {
  return useContext(ThemeContext);
}

export default useTheme;

Χρήση:


import React from 'react';
import useTheme from './useTheme';

function MyComponent() {
  const { theme, toggleTheme } = useTheme();

  return (
    <div style={{ backgroundColor: theme.background, color: theme.color }}>
      <p>This is my component.</p>
      <button onClick={toggleTheme}>Toggle Theme</button>
    </div>
  );
}

export default MyComponent;

3. Debouncing και Throttling

Το Debouncing και το throttling είναι τεχνικές που χρησιμοποιούνται για τον έλεγχο του ρυθμού με τον οποίο εκτελείται μια συνάρτηση. Τα Custom hooks μπορούν να χρησιμοποιηθούν για να ενθυλακώσουν αυτήν τη λογική, καθιστώντας εύκολη την εφαρμογή αυτών των τεχνικών σε χειριστές συμβάντων.


import { useState, useEffect, useRef } from 'react';

function useDebounce(value, delay) {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const handler = setTimeout(() => {
      setDebouncedValue(value);
    }, delay);

    return () => {
      clearTimeout(handler);
    };
  }, [value, delay]);

  return debouncedValue;
}

export default useDebounce;

Χρήση:


import React, { useState } from 'react';
import useDebounce from './useDebounce';

function SearchInput() {
  const [searchValue, setSearchValue] = useState('');
  const debouncedSearchValue = useDebounce(searchValue, 500); // Debounce for 500ms

  useEffect(() => {
    // Perform search with debouncedSearchValue
    console.log('Searching for:', debouncedSearchValue);
    // Replace console.log with your actual search logic
  }, [debouncedSearchValue]);

  const handleChange = (event) => {
    setSearchValue(event.target.value);
  };

  return (
    <input
      type="text"
      value={searchValue}
      onChange={handleChange}
      placeholder="Search..."
    />
  );
}

export default SearchInput;

Βέλτιστες πρακτικές για τη συγγραφή Custom Hooks

Για να διασφαλίσετε ότι τα custom hooks σας είναι αποτελεσματικά και συντηρήσιμα, ακολουθήστε αυτές τις βέλτιστες πρακτικές:

Παγκόσμιες Σκέψεις

Κατά την ανάπτυξη εφαρμογών για ένα παγκόσμιο κοινό, λάβετε υπόψη τα ακόλουθα:

Παράδειγμα: Διεθνοποιημένη μορφοποίηση ημερομηνίας με ένα Custom Hook


import { useState, useEffect } from 'react';
import { DateTimeFormat } from 'intl';

function useFormattedDate(date, locale) {
  const [formattedDate, setFormattedDate] = useState('');

  useEffect(() => {
    try {
      const formatter = new DateTimeFormat(locale, {
        year: 'numeric',
        month: 'long',
        day: 'numeric',
      });
      setFormattedDate(formatter.format(date));
    } catch (error) {
      console.error('Error formatting date:', error);
      setFormattedDate('Invalid Date');
    }
  }, [date, locale]);

  return formattedDate;
}

export default useFormattedDate;

Χρήση:


import React from 'react';
import useFormattedDate from './useFormattedDate';

function MyComponent() {
  const today = new Date();
  const enDate = useFormattedDate(today, 'en-US');
  const frDate = useFormattedDate(today, 'fr-FR');
  const deDate = useFormattedDate(today, 'de-DE');

  return (
    <div>
      <p>US Date: {enDate}</p>
      <p>French Date: {frDate}</p>
      <p>German Date: {deDate}</p>
    </div>
  );
}

export default MyComponent;

Συμπέρασμα

Τα React custom hooks είναι ένας ισχυρός μηχανισμός για την εξαγωγή και την επαναχρησιμοποίηση της λογικής των components. Αξιοποιώντας τα custom hooks, μπορείτε να γράψετε καθαρότερο, πιο συντηρήσιμο και δοκιμαστικό κώδικα. Καθώς γίνεστε πιο ικανοί με το React, η εξοικείωση με τα custom hooks θα βελτιώσει σημαντικά την ικανότητά σας να δημιουργείτε σύνθετες και επεκτάσιμες εφαρμογές. Θυμηθείτε να ακολουθείτε τις βέλτιστες πρακτικές και να λαμβάνετε υπόψη τους παγκόσμιους παράγοντες κατά την ανάπτυξη custom hooks για να διασφαλίσετε ότι είναι αποτελεσματικά και προσβάσιμα σε ένα ποικίλο κοινό. Αγκαλιάστε τη δύναμη των custom hooks και αναβαθμίστε τις δεξιότητές σας στην ανάπτυξη React!

React Custom Hooks: Εξαγωγή Λογικής Component για Επαναχρησιμοποίηση | MLOG