Inferno предоставляет мощный механизм для работы с хуками, позволяя
управлять состоянием компонентов и их жизненным циклом с высокой
производительностью. Хуки — это функции, которые позволяют
«подключаться» к состоянию и другим возможностям Inferno без
использования классов. Основные встроенные хуки включают
useState, useEffect, useRef,
useMemo и useCallback.
useState создаёт локальное состояние
внутри функционального компонента. Его использование аналогично React,
однако Inferno реализует его с минимальной нагрузкой на рендеринг,
обеспечивая более быструю реакцию интерфейса.
import { useState } from 'inferno-hooks';
function Counter() {
const [count, setCount] = useState(0);
return (
<button onCl ick={() => setCount(count + 1)}>
{count}
</button>
);
}
useEffect позволяет выполнять побочные
эффекты после рендера компонента, например, подписки на события или
запросы к API. В Inferno он оптимизирован для минимизации лишних вызовов
и очищений.
import { useEffect } from 'inferno-hooks';
function Timer() {
useEffect(() => {
const interval = setInterval(() => console.log('tick'), 1000);
return () => clearInterval(interval);
}, []);
return <div>Таймер запущен</div>;
}
Создание собственного хука начинается с функции, название которой
должно начинаться с use. Внутри функции могут
использоваться другие хуки, состояние и логика обработки эффектов.
Пример пользовательского хука
useWindowWidth:
import { useState, useEffect } from 'inferno-hooks';
function useWindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return width;
}
Этот хук инкапсулирует логику отслеживания ширины окна и может быть повторно использован в разных компонентах без дублирования кода.
Пользовательские хуки могут принимать аргументы для настройки поведения. Важно грамотно управлять зависимостями в эффектах, чтобы избежать лишних перерендеров.
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let isMounted = true;
setLoading(true);
fetch(url)
.then(response => response.json())
.then(json => {
if (isMounted) {
setData(json);
setLoading(false);
}
});
return () => { isMounted = false; };
}, [url]);
return { data, loading };
}
Хук useFetch демонстрирует, как можно безопасно работать
с асинхронными операциями и предотвращать обновление состояния после
размонтирования компонента.
Собственные хуки можно комбинировать для создания более сложной
функциональности. Например, объединение useWindowWidth и
useFetch позволяет подгружать данные в зависимости от
ширины экрана:
function useResponsiveData(apiUrl) {
const width = useWindowWidth();
const { data, loading } = useFetch(`${apiUrl}?width=${width}`);
return { data, loading, width };
}
Inferno поддерживает создание контекста через
createContext и его использование в пользовательских хуках.
Это позволяет централизованно управлять состоянием приложения.
import { createContext } from 'inferno';
import { useContext, useState } from 'inferno-hooks';
const ThemeContext = createContext('light');
function useTheme() {
return useContext(ThemeContext);
}
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
Пользовательские хуки могут включать мемоизацию значений через
useMemo и функций через useCallback для
уменьшения количества лишних рендеров и пересозданий функций.
import { useMemo, useCallback } from 'inferno-hooks';
function useSortedData(data) {
const sorted = useMemo(() => data.slice().sort(), [data]);
const getItem = useCallback(index => sorted[index], [sorted]);
return { sorted, getItem };
}
use.Создание собственных хуков в Inferno позволяет структурировать код, сделать его более читаемым и расширяемым, одновременно обеспечивая высокую производительность за счет внутренней оптимизации фреймворка.