Lietuvių

Sužinokite, kaip naudoti „React“ individualizuotus „hook'us“, norint iškelti ir pakartotinai panaudoti komponentų logiką, taip pagerinant kodo palaikymą ir testavimą.

React individualizuoti „hook'ai“: komponentų logikos iškėlimas pakartotiniam naudojimui

React „hook'ai“ sukėlė revoliuciją React komponentų rašyme, pasiūlydami elegantiškesnį ir efektyvesnį būdą valdyti būseną (state) ir šalutinius poveikius (side effects). Tarp įvairių galimų „hook'ų“, individualizuoti „hook'ai“ išsiskiria kaip galingas įrankis komponentų logikai iškelti ir pakartotinai naudoti. Šiame straipsnyje pateikiamas išsamus vadovas, kaip suprasti ir įdiegti React individualizuotus „hook'us“, suteikiant galimybę kurti lengviau prižiūrimas, testuojamas ir plečiamas aplikacijas.

Kas yra React individualizuoti „hook'ai“?

Iš esmės, individualizuotas „hook'as“ yra JavaScript funkcija, kurios pavadinimas prasideda žodžiu „use“ ir kuri gali kviesti kitus „hook'us“. Tai leidžia iškelti komponentų logiką į pakartotinai naudojamas funkcijas, taip pašalinant kodo dubliavimą ir skatinant švaresnę komponentų struktūrą. Skirtingai nuo įprastų React komponentų, individualizuoti „hook'ai“ neatvaizduoja jokios vartotojo sąsajos; jie tiesiog inkapsuliuoja logiką.

Galvokite apie juos kaip apie pakartotinai naudojamas funkcijas, kurios gali pasiekti React būseną ir gyvavimo ciklo ypatybes. Tai puikus būdas dalytis būseną turinčia logika tarp skirtingų komponentų, nesinaudojant aukštesnės eilės komponentais (higher-order components) ar atvaizdavimo savybėmis (render props), kurie dažnai gali lemti sunkiai skaitomą ir prižiūrimą kodą.

Kodėl naudoti individualizuotus „hook'us“?

Individualizuotų „hook'ų“ naudojimo privalumai yra gausūs:

Pirmojo individualizuoto „hook'o“ sukūrimas

Iliustruokime individualizuoto „hook'o“ sukūrimą ir naudojimą praktiniu pavyzdžiu: duomenų gavimas iš API.

Pavyzdys: useFetch – duomenų gavimo „hook'as“

Įsivaizduokite, kad jums dažnai reikia gauti duomenis iš skirtingų API savo React aplikacijoje. Užuot kartojus duomenų gavimo logiką kiekviename komponente, galite sukurti 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 klaida! Būsena: ${response.status}`);
        }
        const json = await response.json();
        setData(json);
        setError(null); // Išvalyti ankstesnes klaidas
      } catch (error) {
        if (error.name === 'AbortError') {
          console.log('Užklausa nutraukta');
        } else {
          setError(error);
        }
        setData(null); // Išvalyti ankstesnius duomenis
      } finally {
        setLoading(false);
      }
    };

    fetchData();

    return () => {
      abortController.abort(); // Išvalymo funkcija, skirta nutraukti užklausą atjungiant komponentą arba pasikeitus URL
    };
  }, [url]); // Iš naujo paleisti efektą, kai pasikeičia URL

  return { data, loading, error };
}

export default useFetch;

Paaiškinimas:

useFetch „hook'o“ naudojimas komponente

Dabar pažiūrėkime, kaip naudoti šį individualizuotą „hook'ą“ React komponente:


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>Kraunami vartotojai...</p>;
  if (error) return <p>Klaida: {error.message}</p>;
  if (!users) return <p>Vartotojų nerasta.</p>;

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

export default UserList;

Paaiškinimas:

Pažangūs individualizuotų „hook'ų“ modeliai

Be paprasto duomenų gavimo, individualizuoti „hook'ai“ gali būti naudojami inkapsuliuoti sudėtingesnę logiką. Štai keletas pažangių modelių:

1. Būsenos valdymas su useReducer

Sudėtingesniems būsenos valdymo scenarijams galite derinti individualizuotus „hook'us“ su useReducer. Tai leidžia valdyti būsenos pasikeitimus labiau nuspėjamu ir organizuotu būdu.


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;

Naudojimas:


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

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

  return (
    <div>
      <p>Skaičius: {count}</p>
      <button onClick={increment}>Didinti</button>
      <button onClick={decrement}>Mažinti</button>
    </div>
  );
}

export default Counter;

2. Konteksto integravimas su useContext

Individualizuoti „hook'ai“ taip pat gali būti naudojami supaprastinti prieigą prie React konteksto (Context). Užuot naudoję useContext tiesiogiai savo komponentuose, galite sukurti individualizuotą „hook'ą“, kuris inkapsuliuoja konteksto prieigos logiką.


import { useContext } from 'react';
import { ThemeContext } from './ThemeContext'; // Darant prielaidą, kad turite ThemeContext

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

export default useTheme;

Naudojimas:


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

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

  return (
    <div style={{ backgroundColor: theme.background, color: theme.color }}>
      <p>Tai mano komponentas.</p>
      <button onClick={toggleTheme}>Perjungti temą</button>
    </div>
  );
}

export default MyComponent;

3. Debouncing ir Throttling

Debouncing ir throttling yra technikos, naudojamos kontroliuoti, kokiu dažniu vykdoma funkcija. Individualizuoti „hook'ai“ gali būti naudojami šiai logikai inkapsuliuoti, todėl lengva taikyti šias technikas įvykių apdorojimo funkcijoms (event handlers).


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;

Naudojimas:


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

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

  useEffect(() => {
    // Atlikti paiešką su atidėta paieškos reikšme (debouncedSearchValue)
    console.log('Ieškoma:', debouncedSearchValue);
    // Pakeiskite console.log savo realia paieškos logika
  }, [debouncedSearchValue]);

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

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

export default SearchInput;

Gerosios praktikos rašant individualizuotus „hook'us“

Siekiant užtikrinti, kad jūsų individualizuoti „hook'ai“ būtų efektyvūs ir lengvai prižiūrimi, laikykitės šių gerųjų praktikų:

Globalūs aspektai

Kurdami aplikacijas pasaulinei auditorijai, atsižvelkite į šiuos dalykus:

Pavyzdys: internacionalizuotas datos formatavimas su individualizuotu „hook'u“


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('Klaida formatuojant datą:', error);
      setFormattedDate('Neteisinga data');
    }
  }, [date, locale]);

  return formattedDate;
}

export default useFormattedDate;

Naudojimas:


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>JAV data: {enDate}</p>
      <p>Prancūzijos data: {frDate}</p>
      <p>Vokietijos data: {deDate}</p>
    </div>
  );
}

export default MyComponent;

Išvada

React individualizuoti „hook'ai“ yra galingas mechanizmas, skirtas iškelti ir pakartotinai naudoti komponentų logiką. Naudodami individualizuotus „hook'us“, galite rašyti švaresnį, lengviau prižiūrimą ir testuojamą kodą. Tobulėjant jūsų įgūdžiams su React, individualizuotų „hook'ų“ įvaldymas ženkliai pagerins jūsų gebėjimą kurti sudėtingas ir plečiamas aplikacijas. Nepamirškite laikytis gerųjų praktikų ir atsižvelgti į globalius veiksnius kurdami individualizuotus „hook'us“, kad užtikrintumėte jų efektyvumą ir prieinamumą įvairiai auditorijai. Išnaudokite individualizuotų „hook'ų“ galią ir pakelkite savo React programavimo įgūdžius į aukštesnį lygį!