Telegram Group & Telegram Channel
Сегодня хочу поделиться с вами простым, но часто необходимым при работе приёмом: созданием и использованием кастомного хука useFetch для загрузки данных. Часто в React-компонентах мы дублируем один и тот же код: ставим загрузку, устанавливаем состояние для data, error и loading, пишем useEffect, чтобы делать вызов API, очищаем эффекты… Всё это можно обобщить в одном месте и переиспользовать во множестве компонент.

Вот базовая реализация хука useFetch:


import { useState, useEffect, useRef } from 'react';

function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

// Чтобы избежать обновления стейта после размонтирования компонента
const isMounted = useRef(true);

useEffect(() => {
// При монтировании флага меняются
isMounted.current = true;

// Начинаем загрузку
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(`Ошибка ${response.status}`);
}
return response.json();
})
.then(json => {
if (isMounted.current) {
setData(json);
setLoading(false);
}
})
.catch(err => {
if (isMounted.current) {
setError(err.message);
setLoading(false);
}
});

// Очистка: помечаем, что компонент размонтирован
return () => {
isMounted.current = false;
};
}, [url]);

return { data, loading, error };
}


Разбор ключевых моментов:
1️⃣ useRef для флага isMounted
Если компонент размонтируется до того, как придёт ответ от сервера, вызов setState внутри промиса может вызвать утечку памяти и предупреждение React. Флаг isMounted.current помогает проверить, что компонент ещё жив.

2️⃣ Состояния data, loading, error
Вынесли все три состояния в хук — теперь в компоненте не нужно повторять одно и то же. Достаточно будет написать:


const { data, loading, error } = useFetch('https://api.example.com/posts');


3️⃣ Параметр url в массиве зависимостей
Если url меняется, хук автоматически запустит новую загрузку.

4️⃣ Обработка ошибок
Мы сразу проверяем response.ok, иначе бросаем исключение, и в .catch устанавливаем error.

Теперь пример использования хука в компоненте:


import React from 'react';
import useFetch from './hooks/useFetch';

function PostsList() {
const { data: posts, loading, error } = useFetch('https://jsonplaceholder.typicode.com/posts');

if (loading) {
return <div>Загрузка...</div>;
}

if (error) {
return <div>Ошибка: {error}</div>;
}

return (
<div>
<h2>Список постов</h2>
<ul>
{posts.map(post => (
<li key={post.id}>
<strong>{post.title}</strong>
<p>{post.body}</p>
</li>
))}
</ul>
</div>
);
}

export default PostsList;


Плюсы такого подхода:

* Меньше дублирования кода. Вместо того чтобы копипастить один и тот же useEffect в десятке компонентов, просто импортируем useFetch.
* Централизованная логика. Если понадобится добавить, скажем, кеширование или отмену запроса через AbortController, меняем только внутри useFetch.
* Чистый код в компонентах. Компонент сосредоточен на отображении, а все детали работы с сетью спрятаны в хук.

Советы по улучшению:

* Можно расширить хук, чтобы принимать не только url, но и опции fetch (метод, заголовки и т.п.).
* Добавить параметр deps (зависимости), чтобы перезапускать запрос не только при изменении URL, а при любой другой переменной.
* Использовать AbortController, чтобы отменять запросы при новых вызовах или при размонтировании:



tg-me.com/React_lib/688
Create:
Last Update:

Сегодня хочу поделиться с вами простым, но часто необходимым при работе приёмом: созданием и использованием кастомного хука useFetch для загрузки данных. Часто в React-компонентах мы дублируем один и тот же код: ставим загрузку, устанавливаем состояние для data, error и loading, пишем useEffect, чтобы делать вызов API, очищаем эффекты… Всё это можно обобщить в одном месте и переиспользовать во множестве компонент.

Вот базовая реализация хука useFetch:


import { useState, useEffect, useRef } from 'react';

function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

// Чтобы избежать обновления стейта после размонтирования компонента
const isMounted = useRef(true);

useEffect(() => {
// При монтировании флага меняются
isMounted.current = true;

// Начинаем загрузку
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(`Ошибка ${response.status}`);
}
return response.json();
})
.then(json => {
if (isMounted.current) {
setData(json);
setLoading(false);
}
})
.catch(err => {
if (isMounted.current) {
setError(err.message);
setLoading(false);
}
});

// Очистка: помечаем, что компонент размонтирован
return () => {
isMounted.current = false;
};
}, [url]);

return { data, loading, error };
}


Разбор ключевых моментов:
1️⃣ useRef для флага isMounted
Если компонент размонтируется до того, как придёт ответ от сервера, вызов setState внутри промиса может вызвать утечку памяти и предупреждение React. Флаг isMounted.current помогает проверить, что компонент ещё жив.

2️⃣ Состояния data, loading, error
Вынесли все три состояния в хук — теперь в компоненте не нужно повторять одно и то же. Достаточно будет написать:


const { data, loading, error } = useFetch('https://api.example.com/posts');


3️⃣ Параметр url в массиве зависимостей
Если url меняется, хук автоматически запустит новую загрузку.

4️⃣ Обработка ошибок
Мы сразу проверяем response.ok, иначе бросаем исключение, и в .catch устанавливаем error.

Теперь пример использования хука в компоненте:


import React from 'react';
import useFetch from './hooks/useFetch';

function PostsList() {
const { data: posts, loading, error } = useFetch('https://jsonplaceholder.typicode.com/posts');

if (loading) {
return <div>Загрузка...</div>;
}

if (error) {
return <div>Ошибка: {error}</div>;
}

return (
<div>
<h2>Список постов</h2>
<ul>
{posts.map(post => (
<li key={post.id}>
<strong>{post.title}</strong>
<p>{post.body}</p>
</li>
))}
</ul>
</div>
);
}

export default PostsList;


Плюсы такого подхода:

* Меньше дублирования кода. Вместо того чтобы копипастить один и тот же useEffect в десятке компонентов, просто импортируем useFetch.
* Централизованная логика. Если понадобится добавить, скажем, кеширование или отмену запроса через AbortController, меняем только внутри useFetch.
* Чистый код в компонентах. Компонент сосредоточен на отображении, а все детали работы с сетью спрятаны в хук.

Советы по улучшению:

* Можно расширить хук, чтобы принимать не только url, но и опции fetch (метод, заголовки и т.п.).
* Добавить параметр deps (зависимости), чтобы перезапускать запрос не только при изменении URL, а при любой другой переменной.
* Использовать AbortController, чтобы отменять запросы при новых вызовах или при размонтировании:

BY React


Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283

Share with your friend now:
tg-me.com/React_lib/688

View MORE
Open in Telegram


telegram Telegram | DID YOU KNOW?

Date: |

What Is Bitcoin?

Bitcoin is a decentralized digital currency that you can buy, sell and exchange directly, without an intermediary like a bank. Bitcoin’s creator, Satoshi Nakamoto, originally described the need for “an electronic payment system based on cryptographic proof instead of trust.” Each and every Bitcoin transaction that’s ever been made exists on a public ledger accessible to everyone, making transactions hard to reverse and difficult to fake. That’s by design: Core to their decentralized nature, Bitcoins aren’t backed by the government or any issuing institution, and there’s nothing to guarantee their value besides the proof baked in the heart of the system. “The reason why it’s worth money is simply because we, as people, decided it has value—same as gold,” says Anton Mozgovoy, co-founder & CEO of digital financial service company Holyheld.

A project of our size needs at least a few hundred million dollars per year to keep going,” Mr. Durov wrote in his public channel on Telegram late last year. “While doing that, we will remain independent and stay true to our values, redefining how a tech company should operate.

telegram from ar


Telegram React
FROM USA