Uzziniet, kā izmantot React pielāgotās funkcijas (hooks), lai izvilktu un atkārtoti izmantotu komponentu loģiku, uzlabojot koda uzturamību, testējamību un kopējo lietojumprogrammas arhitektūru.
React pielāgotās funkcijas (Hooks): Komponentu loģikas izvilkšana atkārtotai izmantošanai
React funkcijas ir revolucionējušas veidu, kā mēs rakstām React komponentus, piedāvājot elegantāku un efektīvāku veidu, kā pārvaldīt stāvokli un blakusefektus. Starp dažādajām pieejamajām funkcijām, pielāgotās funkcijas izceļas kā spēcīgs rīks komponentu loģikas izvilkšanai un atkārtotai izmantošanai. Šis raksts sniedz visaptverošu ceļvedi, lai izprastu un ieviestu React pielāgotās funkcijas, dodot jums iespēju veidot vieglāk uzturamas, testējamas un mērogojamas lietojumprogrammas.
Kas ir React pielāgotās funkcijas (Custom Hooks)?
Būtībā pielāgotā funkcija ir JavaScript funkcija, kuras nosaukums sākas ar "use" un kas var izsaukt citas funkcijas. Tā ļauj jums izvilkt komponentu loģiku atkārtoti izmantojamās funkcijās, tādējādi novēršot koda dublēšanos un veicinot tīrāku komponentu struktūru. Atšķirībā no parastajiem React komponentiem, pielāgotās funkcijas neatveido nekādu lietotāja interfeisu; tās vienkārši inkapsulē loģiku.
Uztveriet tās kā atkārtoti izmantojamas funkcijas, kas var piekļūt React stāvokļa un dzīves cikla funkcijām. Tās ir fantastisks veids, kā koplietot stāvokļa loģiku starp dažādiem komponentiem, neizmantojot augstākas kārtas komponentus vai render props, kas bieži vien var padarīt kodu grūti lasāmu un uzturamu.
Kāpēc izmantot pielāgotās funkcijas?
Pielāgoto funkciju izmantošanas priekšrocības ir daudzas:
- Atkārtota izmantošana: Uzrakstiet loģiku vienreiz un izmantojiet to vairākos komponentos. Tas ievērojami samazina koda dublēšanos un padara jūsu lietojumprogrammu vieglāk uzturamu.
- Uzlabota koda organizācija: Kompleksas loģikas izvilkšana pielāgotajās funkcijās sakārto jūsu komponentus, padarot tos vieglāk lasāmus un saprotamus. Komponenti vairāk koncentrējas uz savām pamatuzdevumiem – atveidošanu.
- Uzlabota testējamība: Pielāgotās funkcijas ir viegli testējamas izolēti. Jūs varat testēt funkcijas loģiku, neatveidojot komponentu, kas noved pie stabilākiem un uzticamākiem testiem.
- Palielināta uzturamība: Kad loģika mainās, jums tā jāatjaunina tikai vienā vietā – pielāgotajā funkcijā – nevis katrā komponentā, kur tā tiek izmantota.
- Samazināts veidnes kods (Boilerplate): Pielāgotās funkcijas var inkapsulēt kopīgus modeļus un atkārtotus uzdevumus, samazinot veidnes koda daudzumu, kas jums jāraksta savos komponentos.
Pirmās pielāgotās funkcijas izveide
Ilustrēsim pielāgotās funkcijas izveidi un lietošanu ar praktisku piemēru: datu iegūšanu no API.
Piemērs: useFetch
- Datu iegūšanas funkcija
Iedomājieties, ka jūsu React lietojumprogrammā bieži jāiegūst dati no dažādām API. Tā vietā, lai atkārtotu datu iegūšanas loģiku katrā komponentā, varat izveidot useFetch
funkciju.
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;
Paskaidrojums:
- Stāvokļa mainīgie: Funkcija izmanto
useState
, lai pārvaldītu datus, ielādes stāvokli un kļūdas stāvokli. - useEffect:
useEffect
funkcija veic datu iegūšanu, kad maināsurl
props. - Kļūdu apstrāde: Funkcija ietver kļūdu apstrādi, lai uztvertu iespējamās kļūdas datu iegūšanas laikā. Tiek pārbaudīts statusa kods, lai nodrošinātu veiksmīgu atbildi.
- Ielādes stāvoklis:
loading
stāvoklis tiek izmantots, lai norādītu, vai dati vēl tiek iegūti. - AbortController: Izmanto AbortController API, lai atceltu datu iegūšanas pieprasījumu, ja komponents tiek atvienots vai URL mainās. Tas novērš atmiņas noplūdes.
- Atgrieztā vērtība: Funkcija atgriež objektu, kas satur
data
,loading
unerror
stāvokļus.
Funkcijas useFetch
izmantošana komponentā
Tagad redzēsim, kā izmantot šo pielāgoto funkciju React komponentā:
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;
Paskaidrojums:
- Komponents importē
useFetch
funkciju. - Tas izsauc funkciju ar API URL.
- Tas dekonstruē atgriezto objektu, lai piekļūtu
data
(pārdēvēts parusers
),loading
unerror
stāvokļiem. - Tas nosacīti atveido atšķirīgu saturu, pamatojoties uz
loading
unerror
stāvokļiem. - Ja dati ir pieejami, tas atveido lietotāju sarakstu.
Papildu pielāgoto funkciju modeļi
Papildus vienkāršai datu iegūšanai, pielāgotās funkcijas var izmantot, lai inkapsulētu sarežģītāku loģiku. Šeit ir daži papildu modeļi:
1. Stāvokļa pārvaldība ar useReducer
Sarežģītākiem stāvokļa pārvaldības scenārijiem varat apvienot pielāgotās funkcijas ar useReducer
. Tas ļauj jums pārvaldīt stāvokļa pārejas paredzamākā un organizētākā veidā.
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;
Lietošana:
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. Konteksta integrācija ar useContext
Pielāgotās funkcijas var izmantot arī, lai vienkāršotu piekļuvi React Context. Tā vietā, lai izmantotu useContext
tieši jūsu komponentos, varat izveidot pielāgotu funkciju, kas inkapsulē konteksta piekļuves loģiku.
import { useContext } from 'react';
import { ThemeContext } from './ThemeContext'; // Assuming you have a ThemeContext
function useTheme() {
return useContext(ThemeContext);
}
export default useTheme;
Lietošana:
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. Debounce un Throttle
Debouncing un throttling ir tehnikas, ko izmanto, lai kontrolētu funkcijas izpildes ātrumu. Pielāgotās funkcijas var izmantot, lai inkapsulētu šo loģiku, tādējādi atvieglojot šo tehniku pielietošanu notikumu apstrādātājiem.
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;
Lietošana:
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;
Labākā prakse pielāgoto funkciju rakstīšanā
Lai nodrošinātu, ka jūsu pielāgotās funkcijas ir efektīvas un uzturamas, ievērojiet šīs labākās prakses:
- Sāciet ar "use": Vienmēr nosauciet savas pielāgotās funkcijas ar prefiksu "use". Šī konvencija norāda React, ka funkcija ievēro funkciju (hooks) noteikumus un to var izmantot funkcionālajos komponentos.
- Koncentrējieties: Katrai pielāgotajai funkcijai jābūt skaidram un konkrētam mērķim. Izvairieties no pārmērīgi sarežģītu funkciju veidošanas, kas veic pārāk daudz pienākumu.
- Atgrieziet noderīgas vērtības: Atgrieziet objektu, kas satur visas vērtības un funkcijas, kas nepieciešamas komponentam, kas izmanto funkciju. Tas padara funkciju elastīgāku un atkārtoti izmantojamu.
- Apstrādājiet kļūdas graciozi: Iekļaujiet kļūdu apstrādi savās pielāgotajās funkcijās, lai novērstu neparedzētu uzvedību jūsu komponentos.
- Apsveriet tīrīšanu: Izmantojiet tīrīšanas funkciju
useEffect
, lai novērstu atmiņas noplūdes un nodrošinātu pareizu resursu pārvaldību. Tas ir īpaši svarīgi, strādājot ar abonementiem, taimeriem vai notikumu klausītājiem. - Rakstiet testus: Rūpīgi testējiet savas pielāgotās funkcijas izolēti, lai pārliecinātos, ka tās darbojas, kā paredzēts.
- Dokumentējiet savas funkcijas: Nodrošiniet skaidru dokumentāciju savām pielāgotajām funkcijām, paskaidrojot to mērķi, lietošanu un iespējamos ierobežojumus.
Globāli apsvērumi
Izstrādājot lietojumprogrammas globālai auditorijai, paturiet prātā sekojošo:
- Internacionalizācija (i18n) un Lokalizācija (l10n): Ja jūsu pielāgotā funkcija apstrādā lietotājam redzamu tekstu vai datus, apsveriet, kā tā tiks internacionalizēta un lokalizēta dažādām valodām un reģioniem. Tas var ietvert bibliotēkas, piemēram,
react-intl
vaii18next
, izmantošanu. - Datuma un laika formatēšana: Ņemiet vērā dažādos datuma un laika formātus, kas tiek izmantoti visā pasaulē. Izmantojiet atbilstošas formatēšanas funkcijas vai bibliotēkas, lai nodrošinātu, ka datumi un laiki tiek pareizi parādīti katram lietotājam.
- Valūtas formatēšana: Līdzīgi, atbilstoši apstrādājiet valūtas formatēšanu dažādiem reģioniem.
- Pieejamība (a11y): Pārliecinieties, ka jūsu pielāgotās funkcijas negatīvi neietekmē jūsu lietojumprogrammas pieejamību. Apsveriet lietotājus ar invaliditāti un ievērojiet labāko pieejamības praksi.
- Veiktspēja: Apzinieties iespējamo veiktspējas ietekmi, ko rada jūsu pielāgotās funkcijas, jo īpaši, strādājot ar sarežģītu loģiku vai lielām datu kopām. Optimizējiet savu kodu, lai nodrošinātu, ka tas labi darbojas lietotājiem dažādās vietās ar atšķirīgu tīkla ātrumu.
Piemērs: Internacionalizēta datuma formatēšana ar pielāgotu funkciju
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;
Lietošana:
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;
Secinājums
React pielāgotās funkcijas ir spēcīgs mehānisms komponentu loģikas izvilkšanai un atkārtotai izmantošanai. Izmantojot pielāgotās funkcijas, jūs varat rakstīt tīrāku, vieglāk uzturamu un testējamu kodu. Kļūstot prasmīgākiem ar React, pielāgoto funkciju apgūšana ievērojami uzlabos jūsu spēju veidot sarežģītas un mērogojamas lietojumprogrammas. Atcerieties ievērot labāko praksi un ņemt vērā globālos faktorus, izstrādājot pielāgotās funkcijas, lai nodrošinātu to efektivitāti un pieejamību daudzveidīgai auditorijai. Izmantojiet pielāgoto funkciju spēku un uzlabojiet savas React izstrādes prasmes!