Універсальні користувацькі хуки

Користувацькі хуки (Custom Hooks) — це потужні інструменти для зменшення дублювання коду, підвищення модульності та абстрагування спільної логіки в додатках на React. Користувацькі хуки за своєю суттю є комбінацією одного або кількох базових хуків React і завжди починаються з префікса "use". У цьому матеріалі я не заглиблюватимусь у деталі користувацьких хук, а зосереджуся на тому, як зробити користувацький хук універсальним. Більше інформації про користувацькі хуки можна знайти тут.

pic

Що таке універсальний (Generic) користувацький хук?

Універсальний користувацький хук (Generic Custom Hook) — це React хук, який може працювати з будь-яким типом даних, приймаючи певну модель даних і функціональність як параметри. Використовуючи TypeScript для визначення універсальних типів, можна зробити ці хуки ще більш гнучкими та потужними. Таким чином, один користувацький хук може працювати з різними типами даних, запобігаючи помилкам через використання неправильних типів і забезпечуючи більш надійну структуру коду.

useFetch

При створенні універсального користувацького хука ми можемо використовувати параметри типів, такі як T або ResponseModel, RequestModel.

import {useEffect, useState} from 'react';  

type UseFetchPropType = {  
 /**  
 * Функція для виклику API та отримання даних.  
 * @param query Модель запиту для API.  
 * @returns Модель відповіді  
 */  
 callData: (query?: RequestModel) => Promise;  
 /**  
 * Запит за замовчуванням для API.  
 */  
 defaultPayload?: RequestModel;  
};  

const useFetch = ({  
 defaultPayload,  
 callData,  
}: UseFetchPropType) => {  
 /**  
 * Стан для відстеження, чи зараз відбувається запит даних.  
 */  
 const [isFetching, setIsFetching] = useState(true);  
 /**  
 * Стан для збереження отриманих даних.  
 */  
 const [data, setData] = useState(undefined);  
 /**  
 * Стан для збереження поточних параметрів запиту.  
 */  
 const [payload, setPayload] = useState(defaultPayload);  

 /**  
 * Стан для відстеження, чи є помилка.  
 */  
 const [error, setError] = useState(false);  

 /**  
 * Ефект для отримання даних щоразу, коли змінюються параметри запиту.  
 */  
 useEffect(() => {  
 setIsFetching(true);  
 callData(payload)  
 .then(res => {  
 setError(false);  
 setData(res);  
 })  
 .catch(() => {  
 setData(undefined);  
 setError(true);  
 })  
 .finally(() => {  
 setIsFetching(false);  
 });  
 }, [payload]);  

 /**  
 * Скидає параметри запиту на значення за замовчуванням.  
 */  
 const resetQuery = () => {  
 setPayload(defaultPayload);  
 };  

 /**  
 * Оновлює параметри запиту з наданими значеннями.  
 * @param updates Частковий об'єкт, що містить властивості для оновлення в запиті.  
 */  
 const updateQuery = (updates: RequestModel) => {  
 const updatedQuery: RequestModel = {  
 ...payload,  
 ...updates,  
 };  

 setPayload(updatedQuery);  
 };  

 return {data, payload, isFetching, error, resetQuery, updateQuery};  
};  

export {useFetch};

Цей хук можна використовувати з будь-яким типом ResponseModel (модель відповіді API) та RequestModel (параметри запиту), що дозволяє використовувати один і той самий хук useFetch для різних API запитів.

Використання

Після того як ми передаємо функцію для виклику сервісу в якості параметра для хука useFetch, а також визначаємо типи даних, ми можемо використовувати цей хук.
Як ви можете побачити в наведеному нижче прикладі, ми зберігаємо типи даних.

import React from 'react';  
import {FlatList, ListRenderItemInfo, Pressable, Text} from 'react-native';  

import {useFetch} from 'services/generalServices/useFecth';  

type FilterModel = {  
 categorydId?: number;  
 brandId?: number;  
};  

type ProductModel = {  
 id: number;  
 name: string;  
 image: string;  
 price: number;  
};  

export const App = () => {  
 const {  
 data,   
 isFetching,   
 error,   
 updateQuery  
} = useFetch({callData: getProducts});  

 function renderProductCard({item}: ListRenderItemInfo) {  
 return {item.name};  
 }  

 function renderEmptyView(item: ListRenderItemInfo) {  
 return <>;  
 }  

 const renderCategories = () => {  
 return (  
  updateQuery({categorydId: 1})}>  
 Categori  

 );  
 };  

 return error ? (  

 ) : (  
  renderProductCard(item)}  
 ListEmptyComponent={!isFetching && data?.length === 0 ? renderEmptyView : null}  
 />  
 );  
};

pic

Завершення

Універсальні користувацькі хуки (Generic Custom Hooks) підвищують повторне використання коду в додатках на React, дозволяючи створювати модульні та гнучкі структури, одночасно забезпечуючи типову безпеку (Type Safety). Такі хуки можуть бути використані для отримання даних через API, управління формами, роботи з локальним сховищем і багатьох інших завдань, а також можуть бути налаштовані відповідно до вашої архітектури проекту.

Сподіваюся, що я зміг додати нові знання до вашого арсеналу. Бажаю вам писати більш ефективний та чистий код. Успіхів у роботі!

Перекладено з: Generic Custom Hooks

Leave a Reply

Your email address will not be published. Required fields are marked *