Avage Reacti kohandatud hookide ja efektide kompositsiooni võimsus, et hallata oma rakendustes keerukaid kõrvalmõjusid. Õppige, kuidas efekte orkestreerida puhtama ja paremini hooldatava koodi saavutamiseks.
Reacti kohandatud hookide efektide kompositsioon: Keerukate efektide orkestreerimine
Reacti kohandatud hookid on muutnud pöördeliselt viisi, kuidas me haldame oma rakendustes olekupõhist loogikat ja kõrvalmõjusid. Kuigi useEffect
on võimas tööriist, võivad keerukad komponendid mitme omavahel põimunud efektiga kiiresti kohmakaks muutuda. Siin tulebki appi efektide kompositsioon – tehnika, mis võimaldab meil jagada keerukad efektid väiksemateks, korduvkasutatavateks kohandatud hookideks, mille tulemuseks on puhtam ja paremini hooldatav kood.
Mis on efektide kompositsioon?
Efektide kompositsioon on praktika, kus kombineeritakse mitu väiksemat efekti, mis on tavaliselt kapseldatud kohandatud hookidesse, et luua suurem ja keerukam efekt. Selle asemel, et kogu loogika ühte useEffect
kutsungisse toppida, loome korduvkasutatavaid funktsionaalsuse ühikuid, mida saab vastavalt vajadusele kokku panna. See lähenemine edendab koodi taaskasutatavust, parandab loetavust ja lihtsustab testimist.
Miks kasutada efektide kompositsiooni?
On mitmeid kaalukaid põhjuseid, miks võtta efektide kompositsioon oma Reacti projektides kasutusele:
- Parem koodi taaskasutatavus: Kohandatud hooke saab taaskasutada mitmes komponendis, vähendades koodi dubleerimist ja parandades hooldatavust.
- Parem loetavus: Keerukate efektide jaotamine väiksemateks, fokusseeritud ühikuteks muudab koodi lihtsamini mõistetavaks ja analüüsitavaks.
- Lihtsustatud testimine: Väiksemaid, eraldatud efekte on lihtsam testida ja siluda.
- Suurenenud modulaarsus: Efektide kompositsioon soodustab modulaarset arhitektuuri, mis teeb funktsionaalsuse lisamise, eemaldamise või muutmise lihtsamaks, mõjutamata rakenduse teisi osi.
- Vähendatud keerukus: Suure hulga kõrvalmõjude haldamine ühes
useEffect
-is võib viia spagetikoodini. Efektide kompositsioon aitab keerukuse jaotada hallatavateks osadeks.
Põhinäide: Andmete pärimise ja Local Storage'i püsivuse kombineerimine
Vaatleme stsenaariumi, kus peame API-st pärima kasutajaandmeid ja salvestama need püsivalt local storage'isse. Ilma efektide kompositsioonita võiksime lõpetada ühe useEffect
-iga, mis tegeleb mõlema ülesandega. Siin on, kuidas saavutada sama tulemus efektide kompositsiooniga:
1. Hooki useFetchData
loomine
See hook vastutab andmete pärimise eest API-st.
import { useState, useEffect } from 'react';
function useFetchData(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const json = await response.json();
setData(json);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}
export default useFetchData;
2. Hooki useLocalStorage
loomine
See hook tegeleb andmete pĂĽsivalt local storage'isse salvestamisega.
import { useState, useEffect } from 'react';
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(error);
return initialValue;
}
});
useEffect(() => {
try {
window.localStorage.setItem(key, JSON.stringify(storedValue));
} catch (error) {
console.error(error);
}
}, [key, storedValue]);
return [storedValue, setStoredValue];
}
export default useLocalStorage;
3. Hookide komponeerimine komponendis
Nüüd saame need hookid komponendis kokku panna, et pärida kasutajaandmeid ja salvestada need püsivalt local storage'isse.
import React from 'react';
import useFetchData from './useFetchData';
import useLocalStorage from './useLocalStorage';
function UserProfile() {
const { data: userData, loading, error } = useFetchData('https://api.example.com/user/profile');
const [storedUserData, setStoredUserData] = useLocalStorage('userProfile', null);
useEffect(() => {
if (userData) {
setStoredUserData(userData);
}
}, [userData, setStoredUserData]);
if (loading) {
return Laen kasutajaprofiili...
;
}
if (error) {
return Viga kasutajaprofiili pärimisel: {error.message}
;
}
if (!userData && !storedUserData) {
return Kasutajaandmed pole saadaval.
;
}
const userToDisplay = storedUserData || userData;
return (
Kasutajaprofiil
Nimi: {userToDisplay.name}
E-post: {userToDisplay.email}
);
}
export default UserProfile;
Selles näites oleme eraldanud andmete pärimise loogika ja local storage'i püsivuse loogika kahte eraldi kohandatud hooki. Komponent UserProfile
seejärel komponeerib need hookid soovitud funktsionaalsuse saavutamiseks. See lähenemine muudab koodi modulaarsemaks, korduvkasutatavaks ja lihtsamini testitavaks.
Täpsemad näited: Keerukate efektide orkestreerimine
Efektide kompositsioon muutub veelgi võimsamaks keerukamate stsenaariumitega tegelemisel. Uurime mõningaid täpsemaid näiteid.
1. Tellimuste ja sĂĽndmuste kuulajate haldamine
Kujutage ette stsenaariumi, kus peate tellima WebSocketi ja kuulama konkreetseid sĂĽndmusi. Samuti peate tegelema puhastamisega, kui komponent lahti ĂĽhendatakse. Siin on, kuidas saate seda hallata efektide kompositsiooni abil:
a. Hooki useWebSocket
loomine
See hook loob WebSocketi ĂĽhenduse ja tegeleb taasĂĽhendamise loogikaga.
import { useState, useEffect, useRef } from 'react';
function useWebSocket(url) {
const [socket, setSocket] = useState(null);
const [isConnected, setIsConnected] = useState(false);
const retryCount = useRef(0);
useEffect(() => {
const connect = () => {
const newSocket = new WebSocket(url);
newSocket.onopen = () => {
console.log('WebSocket connected');
setIsConnected(true);
retryCount.current = 0;
};
newSocket.onclose = () => {
console.log('WebSocket disconnected');
setIsConnected(false);
// Exponential backoff for reconnection
const timeout = Math.min(3000 * Math.pow(2, retryCount.current), 60000);
retryCount.current++;
console.log(`Reconnecting in ${timeout/1000} seconds...`);
setTimeout(connect, timeout);
};
newSocket.onerror = (error) => {
console.error('WebSocket error:', error);
};
setSocket(newSocket);
};
connect();
return () => {
if (socket) {
socket.close();
}
};
}, [url]);
return { socket, isConnected };
}
export default useWebSocket;
b. Hooki useEventListener
loomine
See hook võimaldab teil lihtsalt kuulata konkreetseid sündmusi WebSocketis.
import { useEffect } from 'react';
function useEventListener(socket, eventName, handler) {
useEffect(() => {
if (!socket) return;
const listener = (event) => handler(event);
socket.addEventListener(eventName, listener);
return () => {
socket.removeEventListener(eventName, listener);
};
}, [socket, eventName, handler]);
}
export default useEventListener;
c. Hookide komponeerimine komponendis
import React, { useState } from 'react';
import useWebSocket from './useWebSocket';
import useEventListener from './useEventListener';
function WebSocketComponent() {
const { socket, isConnected } = useWebSocket('wss://echo.websocket.events');
const [message, setMessage] = useState('');
const [receivedMessages, setReceivedMessages] = useState([]);
useEventListener(socket, 'message', (event) => {
setReceivedMessages((prevMessages) => [...prevMessages, event.data]);
});
const sendMessage = () => {
if (socket && isConnected) {
socket.send(message);
setMessage('');
}
};
return (
WebSocketi näide
Ăśhenduse staatus: {isConnected ? 'Ăśhendatud' : 'Ăśhenduseta'}
setMessage(e.target.value)}
placeholder="Sisesta sõnum"
/>
Vastuvõetud sõnumid:
{receivedMessages.map((msg, index) => (
- {msg}
))}
);
}
export default WebSocketComponent;
Selles näites haldab useWebSocket
WebSocketi ĂĽhendust, sealhulgas taasĂĽhendamise loogikat, samas kui useEventListener
pakub puhast viisi konkreetsete sĂĽndmuste tellimiseks. Komponent WebSocketComponent
komponeerib need hookid, et luua täisfunktsionaalne WebSocketi klient.
2. Asünkroonsete operatsioonide orkestreerimine sõltuvustega
Mõnikord tuleb efekte käivitada kindlas järjekorras või teatud sõltuvuste alusel. Oletame, et peate pärima kasutajaandmed, seejärel pärima nende postitused kasutaja ID alusel ja seejärel värskendama kasutajaliidest. Saate kasutada efektide kompositsiooni nende asünkroonsete operatsioonide orkestreerimiseks.
a. Hooki useUserData
loomine
See hook pärib kasutajaandmeid.
import { useState, useEffect } from 'react';
function useUserData(userId) {
const [userData, setUserData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const json = await response.json();
setUserData(json);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
fetchData();
}, [userId]);
return { userData, loading, error };
}
export default useUserData;
b. Hooki useUserPosts
loomine
See hook pärib kasutaja postitusi kasutaja ID alusel.
import { useState, useEffect } from 'react';
function useUserPosts(userId) {
const [userPosts, setUserPosts] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
if (!userId) {
setUserPosts(null);
setLoading(false);
return;
}
const fetchPosts = async () => {
try {
const response = await fetch(`https://api.example.com/users/${userId}/posts`);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const json = await response.json();
setUserPosts(json);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
fetchPosts();
}, [userId]);
return { userPosts, loading, error };
}
export default useUserPosts;
c. Hookide komponeerimine komponendis
import React, { useState } from 'react';
import useUserData from './useUserData';
import useUserPosts from './useUserPosts';
function UserProfileWithPosts() {
const [userId, setUserId] = useState(1); // Start with a default user ID
const { userData, loading: userLoading, error: userError } = useUserData(userId);
const { userPosts, loading: postsLoading, error: postsError } = useUserPosts(userId);
return (
Kasutajaprofiil postitustega
setUserId(parseInt(e.target.value, 10))}
/>
{userLoading ? Laen kasutajaandmeid...
: null}
{userError ? Viga kasutajaandmete laadimisel: {userError.message}
: null}
{userData ? (
Kasutaja andmed
Nimi: {userData.name}
E-post: {userData.email}
) : null}
{postsLoading ? Laen kasutaja postitusi...
: null}
{postsError ? Viga kasutaja postituste laadimisel: {postsError.message}
: null}
{userPosts ? (
Kasutaja postitused
{userPosts.map((post) => (
- {post.title}
))}
) : null}
);
}
export default UserProfileWithPosts;
Selles näites sõltub useUserPosts
userId
-st. Hook pärib postitusi ainult siis, kui kehtiv userId
on saadaval. See tagab, et efektid käivitatakse õiges järjekorras ja kasutajaliidest värskendatakse vastavalt.
Efektide kompositsiooni parimad praktikad
Et efektide kompositsioonist maksimumi võtta, arvestage järgmiste parimate tavadega:
- Ühe vastutuse printsiip: Igal kohandatud hookil peaks olema üks, selgelt määratletud vastutus.
- Kirjeldavad nimed: Kasutage oma kohandatud hookidele kirjeldavaid nimesid, et nende eesmärk oleks selgelt näidatud.
- Sõltuvuste massiivid: Hallake hoolikalt sõltuvuste massiive oma
useEffect
kutsungites, et vältida ebavajalikke uuesti renderdamisi või lõputuid tsükleid. - Testimine: Kirjutage oma kohandatud hookidele ühiktestid, et tagada nende ootuspärane käitumine.
- Dokumentatsioon: Dokumenteerige oma kohandatud hookid, et neid oleks lihtsam mõista ja taaskasutada.
- Vältige üle-abstraheerimist: Ärge konstrueerige oma kohandatud hooke üle. Hoidke need lihtsad ja fokusseeritud.
- Kaaluge veatöötlust: Rakendage oma kohandatud hookides tugev veatöötlus, et ootamatute olukordadega sujuvalt toime tulla.
Globaalsed kaalutlused
Reacti rakenduste arendamisel globaalsele publikule pidage silmas järgmisi kaalutlusi:
- Rahvusvahelistamine (i18n): Kasutage mitme keele toetamiseks teeki nagu
react-intl
võii18next
. - Lokaliseerimine (l10n): Kohandage oma rakendus erinevatele piirkondlikele eelistustele, nagu kuupäeva- ja numbrivormingud.
- Juurdepääsetavus (a11y): Tagage, et teie rakendus oleks puuetega kasutajatele juurdepääsetav, järgides WCAG juhiseid.
- Jõudlus: Optimeerige oma rakendus erinevate võrgutingimuste ja seadmevõimaluste jaoks. Kaaluge tehnikate nagu koodi tükeldamine ja laisk laadimine kasutamist.
- Sisuedastusvõrgud (CDN): Kasutage CDN-i, et edastada oma rakenduse varasid serveritest, mis asuvad teie kasutajatele lähemal, vähendades latentsust ja parandades jõudlust.
- Ajavööndid: Kuupäevade ja kellaaegadega tegelemisel arvestage erinevate ajavöönditega ja kasutage sobivaid teeke nagu
moment-timezone
võidate-fns-timezone
.
Näide: Rahvusvahelistatud kuupäeva vormindamine
import { useIntl, FormattedDate } from 'react-intl';
function MyComponent() {
const intl = useIntl();
const now = new Date();
return (
Praegune kuupäev:
Praegune kuupäev (saksa keeles):
);
}
export default MyComponent;
Kokkuvõte
Efektide kompositsioon on võimas tehnika keerukate kõrvalmõjude haldamiseks Reacti rakendustes. Jagades suured efektid väiksemateks, korduvkasutatavateks kohandatud hookideks, saate parandada koodi taaskasutatavust, suurendada loetavust, lihtsustada testimist ja vähendada üldist keerukust. Võtke omaks efektide kompositsioon, et luua puhtamaid, paremini hooldatavaid ja skaleeritavaid Reacti rakendusi globaalsele publikule.