Ilovalaringizdagi murakkab yon effektlarni boshqarish uchun React maxsus hooklari va effektlar kompozitsiyasi kuchini oching. Tozaroq, qo'llab-quvvatlanadigan kod uchun effektlarni qanday boshqarishni o'rganing.
React maxsus hook effektlari kompozitsiyasi: Murakkab effektlarni boshqarishni o'zlashtirish
React maxsus hooklari ilovalarimizda holatga bog'liq mantiqni va yon effektlarni boshqarish usulimizni inqilob qildi. useEffect
kuchli vosita bo'lsa-da, murakkab komponentlar bir-biri bilan bog'langan bir nechta effektlar tufayli tezda boshqarib bo'lmaydigan holga kelishi mumkin. Aynan shu yerda effektlar kompozitsiyasi yordamga keladi – bu murakkab effektlarni kichikroq, qayta ishlatiladigan maxsus hooklarga bo'lish imkonini beruvchi texnika bo'lib, natijada toza va qo'llab-quvvatlanishi osonroq kodga erishiladi.
Effektlar kompozitsiyasi nima?
Effektlar kompozitsiyasi – bu odatda maxsus hooklarga o'ralgan bir nechta kichikroq effektlarni birlashtirib, kattaroq va murakkabroq effekt yaratish amaliyotidir. Barcha mantiqni bitta useEffect
chaqiruviga tiqishtirish o'rniga, biz kerak bo'lganda birgalikda tuzilishi mumkin bo'lgan qayta ishlatiladigan funksionallik birliklarini yaratamiz. Bu yondashuv kodni qayta ishlatishni rag'batlantiradi, o'qilishi osonligini yaxshilaydi va testlashni soddalashtiradi.
Nima uchun effektlar kompozitsiyasidan foydalanish kerak?
React loyihalaringizda effektlar kompozitsiyasini qabul qilish uchun bir nechta jiddiy sabablar mavjud:
- Koddan qayta foydalanish imkoniyatining yaxshilanishi: Maxsus hooklar bir nechta komponentlarda qayta ishlatilishi mumkin, bu esa kodning takrorlanishini kamaytiradi va uni qo'llab-quvvatlashni yaxshilaydi.
- O'qilishi osonligining oshishi: Murakkab effektlarni kichikroq, aniq maqsadli birliklarga bo'lish kodni tushunish va tahlil qilishni osonlashtiradi.
- Soddalashtirilgan testlash: Kichikroq, ajratilgan effektlarni testlash va tuzatish osonroq.
- Modullikning oshishi: Effektlar kompozitsiyasi modulli arxitekturani rag'batlantiradi, bu esa ilovaning boshqa qismlariga ta'sir qilmasdan funksionallikni qo'shish, olib tashlash yoki o'zgartirishni osonlashtiradi.
- Murakkablikning kamayishi: Bitta
useEffect
'da ko'p sonli yon effektlarni boshqarish "spagetti kod"ga olib kelishi mumkin. Effektlar kompozitsiyasi murakkablikni boshqariladigan qismlarga bo'lishga yordam beradi.
Asosiy misol: Ma'lumotlarni olish va Local Storage'da saqlashni birlashtirish
Keling, API'dan foydalanuvchi ma'lumotlarini olishimiz va uni local storage'da saqlashimiz kerak bo'lgan stsenariyni ko'rib chiqaylik. Effektlar kompozitsiyasisiz, biz ikkala vazifani ham bajaradigan bitta useEffect
bilan yakunlashimiz mumkin. Effektlar kompozitsiyasi yordamida xuddi shu natijaga qanday erishish mumkinligi quyida ko'rsatilgan:
1. useFetchData
hook'ini yaratish
Ushbu hook API'dan ma'lumotlarni olish uchun mas'uldir.
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. useLocalStorage
hook'ini yaratish
Ushbu hook ma'lumotlarni local storage'da saqlashni boshqaradi.
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. Hooklarni komponentda birlashtirish
Endi biz foydalanuvchi ma'lumotlarini olish va uni local storage'da saqlash uchun ushbu hooklarni komponentda birlashtirishimiz mumkin.
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 Foydalanuvchi profilini yuklash...
;
}
if (error) {
return Foydalanuvchi profilini yuklashda xatolik: {error.message}
;
}
if (!userData && !storedUserData) {
return Foydalanuvchi ma'lumotlari mavjud emas.
;
}
const userToDisplay = storedUserData || userData;
return (
Foydalanuvchi profili
Ism: {userToDisplay.name}
Email: {userToDisplay.email}
);
}
export default UserProfile;
Ushbu misolda biz ma'lumotlarni olish mantig'ini va local storage'da saqlash mantig'ini ikkita alohida maxsus hookka ajratdik. Keyin UserProfile
komponenti kerakli funksionallikka erishish uchun ushbu hooklarni birlashtiradi. Bu yondashuv kodni yanada modulli, qayta ishlatiladigan va testlash uchun oson qiladi.
Murakkab misollar: Murakkab effektlarni boshqarish
Effektlar kompozitsiyasi yanada murakkab stsenariylar bilan ishlaganda yanada kuchliroq bo'ladi. Keling, ba'zi ilg'or misollarni ko'rib chiqaylik.
1. Obunalar va hodisa tinglovchilarini boshqarish
Siz WebSocket'ga obuna bo'lishingiz va ma'lum hodisalarni tinglashingiz kerak bo'lgan stsenariyni ko'rib chiqing. Shuningdek, komponent o'chirilganda tozalash ishlarini bajarishingiz kerak. Buni boshqarish uchun effektlar kompozitsiyasidan qanday foydalanish mumkinligi quyida ko'rsatilgan:
a. useWebSocket
hook'ini yaratish
Ushbu hook WebSocket ulanishini o'rnatadi va qayta ulanish mantig'ini boshqaradi.
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. useEventListener
hook'ini yaratish
Ushbu hook sizga WebSocket'dagi ma'lum hodisalarni osongina tinglash imkonini beradi.
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. Hooklarni komponentda birlashtirish
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 (
WebSocket misoli
Ulanish holati: {isConnected ? 'Ulangan' : 'Uzlangan'}
setMessage(e.target.value)}
placeholder="Xabar kiriting"
/>
Qabul qilingan xabarlar:
{receivedMessages.map((msg, index) => (
- {msg}
))}
);
}
export default WebSocketComponent;
Ushbu misolda useWebSocket
WebSocket ulanishini, shu jumladan qayta ulanish mantig'ini boshqaradi, useEventListener
esa ma'lum hodisalarga obuna bo'lishning toza usulini taqdim etadi. WebSocketComponent
to'liq funksional WebSocket mijozini yaratish uchun ushbu hooklarni birlashtiradi.
2. Bog'liqliklarga ega asinxron operatsiyalarni boshqarish
Ba'zan effektlar ma'lum bir tartibda yoki ma'lum bog'liqliklarga asoslanib ishga tushirilishi kerak. Aytaylik, siz foydalanuvchi ma'lumotlarini, so'ngra foydalanuvchi ID'siga asoslanib ularning postlarini olishingiz va keyin interfeysni yangilashingiz kerak. Siz ushbu asinxron operatsiyalarni boshqarish uchun effektlar kompozitsiyasidan foydalanishingiz mumkin.
a. useUserData
hook'ini yaratish
Ushbu hook foydalanuvchi ma'lumotlarini oladi.
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. useUserPosts
hook'ini yaratish
Ushbu hook foydalanuvchi ID'siga asoslanib uning postlarini oladi.
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. Hooklarni komponentda birlashtirish
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 (
Postlar bilan foydalanuvchi profili
setUserId(parseInt(e.target.value, 10))}
/>
{userLoading ? Foydalanuvchi ma'lumotlari yuklanmoqda...
: null}
{userError ? Foydalanuvchi ma'lumotlarini yuklashda xatolik: {userError.message}
: null}
{userData ? (
Foydalanuvchi tafsilotlari
Ism: {userData.name}
Email: {userData.email}
) : null}
{postsLoading ? Foydalanuvchi postlari yuklanmoqda...
: null}
{postsError ? Foydalanuvchi postlarini yuklashda xatolik: {postsError.message}
: null}
{userPosts ? (
Foydalanuvchi postlari
{userPosts.map((post) => (
- {post.title}
))}
) : null}
);
}
export default UserProfileWithPosts;
Ushbu misolda useUserPosts
userId
'ga bog'liq. Hook faqat yaroqli userId
mavjud bo'lganda postlarni oladi. Bu effektlarning to'g'ri tartibda ishga tushirilishini va interfeysning shunga mos ravishda yangilanishini ta'minlaydi.
Effektlar kompozitsiyasi uchun eng yaxshi amaliyotlar
Effektlar kompozitsiyasidan maksimal darajada foydalanish uchun quyidagi eng yaxshi amaliyotlarni ko'rib chiqing:
- Yagona mas'uliyat tamoyili: Har bir maxsus hook bitta, aniq belgilangan mas'uliyatga ega bo'lishi kerak.
- Tavsiflovchi nomlar: Maxsus hooklaringizning maqsadini aniq ko'rsatish uchun tavsiflovchi nomlardan foydalaning.
- Bog'liqliklar massivlari: Keraksiz qayta renderlar yoki cheksiz tsikllarni oldini olish uchun
useEffect
chaqiruvlaringizdagi bog'liqliklar massivlarini diqqat bilan boshqaring. - Testlash: Maxsus hooklaringizning kutilganidek ishlashini ta'minlash uchun ular uchun unit testlar yozing.
- Hujjatlashtirish: Maxsus hooklaringizni tushunish va qayta ishlatishni osonlashtirish uchun ularni hujjatlashtiring.
- Haddan tashqari abstraksiyadan saqlaning: Maxsus hooklaringizni ortiqcha murakkablashtirmang. Ularni oddiy va aniq maqsadli saqlang.
- Xatoliklarni qayta ishlashni hisobga oling: Kutilmagan vaziyatlarni chiroyli tarzda hal qilish uchun maxsus hooklaringizda mustahkam xatoliklarni qayta ishlashni joriy qiling.
Global jihatlar
Global auditoriya uchun React ilovalarini ishlab chiqishda quyidagi jihatlarni yodda tuting:
- Xalqarolashtirish (i18n): Bir nechta tillarni qo'llab-quvvatlash uchun
react-intl
yokii18next
kabi kutubxonalardan foydalaning. - Mahalliylashtirish (l10n): Ilovangizni sana va raqam formatlari kabi turli mintaqaviy afzalliklarga moslashtiring.
- Kirish imkoniyati (a11y): WCAG yo'riqnomalariga rioya qilgan holda ilovangiz nogironligi bo'lgan foydalanuvchilar uchun ochiq ekanligiga ishonch hosil qiling.
- Ishlash samaradorligi: Ilovangizni turli tarmoq sharoitlari va qurilma imkoniyatlari uchun optimallashtiring. Kodni bo'lish va "dangasa yuklash" kabi usullardan foydalanishni ko'rib chiqing.
- Kontent yetkazib berish tarmoqlari (CDN): Ilovangiz aktivlarini foydalanuvchilarga yaqinroq joylashgan serverlardan yetkazib berish uchun CDN dan foydalaning, bu kechikishni kamaytiradi va ishlash samaradorligini oshiradi.
- Vaqt zonalari: Sana va vaqt bilan ishlashda turli vaqt zonalariga e'tibor bering va
moment-timezone
yokidate-fns-timezone
kabi tegishli kutubxonalardan foydalaning.
Misol: Xalqarolashtirilgan sana formatlash
import { useIntl, FormattedDate } from 'react-intl';
function MyComponent() {
const intl = useIntl();
const now = new Date();
return (
Joriy sana:
Joriy sana (nemischa):
);
}
export default MyComponent;
Xulosa
Effektlar kompozitsiyasi React ilovalarida murakkab yon effektlarni boshqarish uchun kuchli usuldir. Katta effektlarni kichikroq, qayta ishlatiladigan maxsus hooklarga bo'lish orqali siz kodni qayta ishlatish imkoniyatini yaxshilashingiz, o'qilishini osonlashtirishingiz, testlashni soddalashtirishingiz va umumiy murakkablikni kamaytirishingiz mumkin. Global auditoriya uchun toza, qo'llab-quvvatlanishi oson va kengaytiriladigan React ilovalarini yaratish uchun effektlar kompozitsiyasini qabul qiling.