Custom React 후크를 사용하여 복잡한 시나리오를 단순화합니다
React의 세계에서 Hooks는 구성 요소를 구축하고 상태를 관리하는 방식에 혁명을 일으켰습니다. 후크의 도입 useState
,,, useEffect
그리고 useContext
개발자에게 깨끗하고 재사용 가능한 코드를 작성하는 데 더 많은 유연성을 부여했습니다. 그러나 내장 후크만으로는 복잡한 논리를 처리하거나 원하는 추상화를 제공하기에 충분하지 않은 시나리오가 있습니다. 맞춤 반응 후크가 들어오는 곳입니다.
사용자 정의 후크를 사용하면 로직을 재사용 가능한 기능으로 캡슐화하여 코드베이스를 클리너하고 유지 관리하기가 가능합니다. 이 기사에서는 복잡한 시나리오를 처리하기 위해 맞춤형 반응 후크를 구축하기위한 고급 기술과 전략을 살펴 보겠습니다.
소개
React 후크의 기본
React 16.8에 React 후크가 도입되어 반응 구성 요소를 구축 할 수있는 방법의 이동이 표시되었습니다. 전통적으로 클래스 구성 요소는 상태 및 수명주기 방법을 관리하는 데 사용되었습니다. 그러나 후크를 사용하면 기능 구성 요소에서 상태 및 기타 반응 기능을 사용할 수 있으므로 더 간단하고 선언적 인 코드가됩니다.
가장 일반적으로 사용되는 후크는 다음과 같습니다.
useState
: 기능 구성 요소의 상태를 관리합니다.useEffect
: 데이터 가져 오기, 구독 및 DOM 조작과 같은 부작용을 처리합니다.useContext
: 소품 시추없이 구성 요소에서 상태를 공유하는 방법을 제공합니다.
React Applications에서 사용자 정의 후크의 역할
내장 후크는 대부분의 시나리오를 다루지 만 복잡한 논리를 여러 구성 요소에서 공유 해야하는 경우가 있습니다. 커스텀 후크는 관련 논리를 함께 그룹화 할 수있는 추상화 계층을 제공합니다. 코드 재사용, 우려 분리 및 더 깨끗한 아키텍처를 허용합니다.
예를 들어, 여러 구성 요소에 동일한 데이터 페치 로직이 필요한 경우 useFetch
이 논리를 중앙 집중화하고 중복성을 방지 할 수 있습니다.
왜 그리고 언제, 맞춤형 후크를 만들 것입니다
코드 재사용 및 추상화
사용자 정의 후크의 주요 이점 중 하나는 코드 재사용 성입니다. 대규모 응용 프로그램에서는 단일 후크로 추상화 될 수있는 반복적 인 논리를 만나는 것이 일반적입니다. 예를 들어, 사용자 인증을 처리하는 후크는 로직을 복제하지 않고 다른 구성 요소에서 사용할 수 있습니다.
사용자 정의 후크를 사용하면 다음을 수행 할 수 있습니다.
- 복잡한 논리를 캡슐화합니다: 구성 요소에서 복잡한 논리를 분리하십시오.
- 코드 일관성을 촉진합니다: 응용 프로그램에서 동일한 논리를 재사용하십시오.
- 유지 관리 가능성을 향상시킵니다: 코드베이스를보다 모듈화하고 관리하기 쉽게 만듭니다.
복잡한 논리 처리
복잡한 시나리오에는 종종 기본 고리가 제공하는 것 이상이 필요합니다. 다음 상황을 고려하십시오.
- 사용자 입력 디 닝: 사용자의 검색 입력을 디바이 션하여 과도한 API 호출을 피하십시오.
- 스로틀 이벤트 청취자: 스크롤 또는 크기 조정과 같은 이벤트 처리 빈도 제한.
- 여러 API 요청 관리: 서로 의존하는 여러 API 통화를 조정합니다.
- 상태 및 검증을 형성합니다: 동적 형태 필드, 검증 및 제출 로직 처리.
이러한 시나리오는 구성 요소에서 직접 처리하기가 어려울 수 있습니다. 사용자 정의 후크를 사용하면 그러한 논리의 관리를 단순화하고 간소화 할 수 있습니다.
커스텀 후크의 해부학 이해
후크 구조 및 이름 지정 규칙
사용자 정의 후크는 본질적으로 내장 된 후크를 내부적으로 사용하는 JavaScript 기능입니다. 그들은 함수 이름을 “사용”으로 접두사하는 규칙을 따랐으며, 이는 React Linter가이를 후크로 올바르게 식별 할 수 있도록합니다. 후크는 최상위 레벨 및 내부 React 기능 구성 요소 또는 기타 사용자 정의 후크에서만 호출되는 것과 같은 후크 규칙에 의존하기 때문에 이것은 중요합니다.
다음은 사용자 정의 후크를위한 기본 템플릿입니다.
function useCustomHook() {
// Define state, effects, and logic here
const [state, setState] = useState(initialValue);
useEffect(() => {
// Side effect logic
return () => {
// Cleanup logic
};
}, [dependencies]);
return state;
}
사용자 정의 후크 구조화시 몇 가지 주요 고려 사항 :
- 나미: 후크의 목적을 나타내는 의미있는 이름을 사용하십시오 (예 :
useFetch
,,,useAuth
,,,useDebounce
). - 국가 관리: 사용을 사용하여 내부 상태를 관리합니다
useState
또는useReducer
. - 부작용: 사용을 사용하여 부작용을 처리합니다
useEffect
필요할 때 적절한 정리를 보장하십시오.
사용자 정의 후크의 상태 관리 및 부작용
상태 관리 및 부작용은 대부분의 사용자 정의 후크에 필수적입니다. 논리의 복잡성에 따라 useState
또는 useReducer
. 예를 들어, 후크가 여러 관련 상태를 관리 해야하는 경우 useReducer
더 나은 조직과 유연성을 제공 할 수 있습니다.
다음은 주 관리 및 부작용이 모두 포함 된 사용자 정의 후크의 예입니다.
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
let isMounted = true;
const fetchData = async () => {
try {
const response = await fetch(url);
const result = await response.json();
if (isMounted) {
setData(result);
setLoading(false);
}
} catch (err) {
if (isMounted) {
setError(err);
setLoading(false);
}
}
};
fetchData();
return () => {
isMounted = false;
};
}, [url]);
return { data, loading, error };
}
이 예에서 useFetch
Hook는 데이터 가져 오기 로직, 상태 관리 및 잠재적 오류를 처리합니다.
복잡한 시나리오를위한 실제 사용자 정의 후크
이제 기본 사항을 이해 했으므로 특정 복잡한 시나리오를 다루는 고급 커스텀 후크를 살펴 보겠습니다.
커스텀 후크로 디포 킹 및 조절을 처리합니다
Decouncing 및 Throttling은 기능이 실행되는 속도를 제어하는 일반적인 기술입니다. 예를 들어, 검색 입력에서 모든 키 스트로크와 함께 요청을 보내지 않도록 API 호출을 분해 할 수 있습니다.
다음은 Decouncing을위한 사용자 정의 후크입니다.
import { useState, useEffect } from 'react';
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
}
// Usage
const debouncedSearchTerm = useDebounce(searchTerm, 500);
스로틀링을 위해 lodash
스로틀 기능 또는 사용자 정의 구현.
Usefetch 후크를 사용하여 데이터를 가져오고 관리합니다
가져 오기 데이터는 React Applications에서 가장 일반적인 작업 중 하나입니다. 맞춤 후크 useFetch
로딩 상태, 오류 및 캐싱을 처리하는 동안 API 요청을 관리하는 데 도움이 될 수 있습니다.
기본을 확장합시다 useFetch
캐싱 및 폴링을 포함하는 훅 :
import { useState, useEffect, useRef } from 'react';
function useFetch(url, options, pollingInterval = null) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const cache = useRef({});
useEffect(() => {
let isMounted = true;
const fetchData = async () => {
if (cache.current[url]) {
setData(cache.current[url]);
setLoading(false);
} else {
try {
const response = await fetch(url, options);
const result = await response.json();
if (isMounted) {
cache.current[url] = result;
setData(result);
setLoading(false);
}
} catch (err) {
if (isMounted) {
setError(err);
setLoading(false);
}
}
}
};
fetchData();
let interval;
if (pollingInterval) {
interval = setInterval(fetchData, pollingInterval);
}
return () => {
isMounted = false;
if (interval) clearInterval(interval);
};
}, [url, options, pollingInterval]);
return { data, loading, error };
}
이것은 향상되었습니다 useFetch
Hook는 캐싱 및 폴링을 지원하므로 API 통화를 최소화하려는 실시간 응용 프로그램 또는 시나리오에 적합합니다.
사용자 정의 후크로 양식 관리
형태는 특히 악명 높다
동적 필드, 검증 및 복잡한 논리가 포함될 때. 사용자 정의 후크는 상태, 검증 및 제출 로직을 캡슐화하여 양식 관리를 단순화 할 수 있습니다.
다음은 a의 예입니다 useForm
훅:
import { useState } from 'react';
function useForm(initialValues, validate) {
const [values, setValues] = useState(initialValues);
const [errors, setErrors] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
const handleChange = (e) => {
const { name, value } = e.target;
setValues({
...values,
[name]: value,
});
};
const handleSubmit = (callback) => (e) => {
e.preventDefault();
const validationErrors = validate(values);
setErrors(validationErrors);
if (Object.keys(validationErrors).length === 0) {
setIsSubmitting(true);
callback();
setIsSubmitting(false);
}
};
return {
values,
errors,
isSubmitting,
handleChange,
handleSubmit,
};
}
// Usage
const validate = (values) => {
const errors = {};
if (!values.email) {
errors.email="Email is required";
}
// Add more validation rules
return errors;
};
const { values, errors, handleChange, handleSubmit } = useForm(
{ email: '' },
validate
);
이것 useForm
후크는 입력 변경, 검증 및 양식 제출을 처리하여 구성 요소의 양식 상태 및 논리를보다 쉽게 관리 할 수 있도록합니다.
커스텀 후크 용 고급 패턴
의존성 및 정리 처리
부작용과 관련된 맞춤형 후크를 구축 할 때 의존성 관리 및 정리를 올바르게 정리하는 것이 중요합니다. 이는 비동기 작업, 구독 또는 타이머를 다룰 때 특히 그렇습니다.
데이터 소스를 구독하고 구성 요소가 마운트를 마치면 청소를 수행 해야하는 시나리오를 고려해 봅시다.
import { useState, useEffect } from 'react';
function useSubscription(dataSource) {
const [data, setData] = useState(dataSource.getInitialData());
useEffect(() => {
const handleDataChange = (newData) => {
setData(newData);
};
dataSource.subscribe(handleDataChange);
return () => {
dataSource.unsubscribe(handleDataChange);
};
}, [dataSource]);
return data;
}
이 후크는 데이터 소스에 가입하고 UNMONTER를 사용하는 구성 요소가 자동으로 정리를 처리합니다. 핵심은 효과의 종속성이 잘 정의되어 있고 정리 기능이 제대로 구독하거나 진행중인 작업을 취소하는지 확인하는 것입니다.
글로벌 주 관리를위한 커스텀 훅 사용
사용자 정의 후크를 사용하여 React 응용 프로그램에서 글로벌 상태를 관리 할 수도 있습니다. Redux와 같은 컨텍스트 및 라이브러리는 상태 관리를위한 인기있는 선택이지만 사용자 정의 후크는 더 간단한 사용 사례를위한 가벼운 대안을 제공합니다.
예를 들어, React ‘s를 사용하여 글로벌 매장을 만들 수 있습니다. useContext
그리고 useReducer
:
import React, { createContext, useContext, useReducer } from 'react';
const GlobalStateContext = createContext();
const GlobalDispatchContext = createContext();
const initialState = {
user: null,
theme: 'light',
};
function reducer(state, action) {
switch (action.type) {
case 'SET_USER':
return { ...state, user: action.payload };
case 'TOGGLE_THEME':
return { ...state, theme: state.theme === 'light' ? 'dark' : 'light' };
default:
return state;
}
}
export function GlobalProvider({ children }) {
const [state, dispatch] = useReducer(reducer, initialState);
return (
{children}
);
}
export function useGlobalState() {
return useContext(GlobalStateContext);
}
export function useGlobalDispatch() {
return useContext(GlobalDispatchContext);
}
이 설정은 다음과 같은 맞춤형 후크를 사용하여 글로벌 상태에 액세스하고 작업을 발송할 수 있습니다. useGlobalState
그리고 useGlobalDispatch
.
사용자 정의 후크 디버깅 및 테스트
후크 테스트를위한 모범 사례
맞춤형 후크 테스트는 특히 부작용, 비동기 작업 또는 복잡한 논리가 포함될 때 어려울 수 있습니다. React Testing Library는 유틸리티와 같은 유틸리티를 제공합니다 renderHook
고리를 분리하여 테스트합니다.
다음은 React Testing Library를 사용하여 사용자 정의 후크 테스트의 예입니다.
import { renderHook, act } from '@testing-library/react-hooks';
import useCounter from './useCounter';
test('should increment counter', () => {
const { result } = renderHook(() => useCounter());
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
test('should reset counter', () => {
const { result } = renderHook(() => useCounter());
act(() => {
result.current.increment();
result.current.reset();
});
expect(result.current.count).toBe(0);
});
이 예에서 useCounter
Hook는 사용자 상호 작용을 시뮬레이션하고 예상 결과를 주장하여 테스트됩니다.
복잡한 커스텀 후크 디버깅
사용자 정의 후크 디버깅은 디버깅 구성 요소와 동일한 원리를 따릅니다. 그러나 후크는 논리를 캡슐화하기 때문에 문제를 식별하는 것이 까다로울 수 있습니다. 사용자 정의 후크 디버깅을위한 몇 가지 팁은 다음과 같습니다.
- 콘솔 로깅: 로그 문을 추가하여 후크 내로 논리 및 상태 변경의 흐름을 추적합니다.
- DevTools를 반응합니다: React DevTools의 “Hooks”패널을 사용하여 사용자 정의 후크가 관리하는 상태 및 효과를 검사하십시오.
- 후크를 분해합니다: 후크가 특히 복잡한 경우 개별적으로 디버깅하기 쉬운 작고 관리하기 쉬운 후크로 분해하십시오.
커스텀 후크의 성능 최적화
불필요한 재 렌즈를 피합니다
Hooks와의 주요 성능 중 하나는 특히 값 비싼 작업을 처리 할 때 불필요한 재 렌즈입니다. 이를 피하기 위해 메모 화 기술을 사용할 수 있습니다 useMemo
그리고 useCallback
.
예를 들어:
import { useMemo } from 'react';
function useExpensiveCalculation(input) {
const result = useMemo(() => {
return performExpensiveCalculation(input);
}, [input]);
return result;
}
사용 useMemo
값 비싼 계산은 다음에만 재 계산됩니다 input
중복 계산을 방지하여 변경됩니다.
메모 화 전략
에 추가 useMemo
사용자 정의 후크를 최적화 할 수 있습니다 useCallback
메모 징수의 경우 다른 후크에 대한 종속성으로 전달 된 기능 :
import { useCallback } from 'react';
function useDebouncedCallback(callback, delay) {
const debouncedCallback = useCallback(
(...args) => {
const handler = setTimeout(() => {
callback(...args);
}, delay);
return () => {
clearTimeout(handler);
};
},
[callback, delay]
);
return debouncedCallback;
}
Memoization은 후크가 필요할 때만 값을 다시 계산하거나 기능을 재현하여 성능을 향상시킵니다.
재사용 가능하고 확장 가능한 커스텀 후크 구축
재사용 가능성을위한 후크 설계
재사용 가능성은 커스텀 후크를 구축 할 때 핵심 원칙입니다. 재사용 가능한 후크 설계를위한 몇 가지 팁은 다음과 같습니다.
- 구성 가능한 옵션을 매개 변수화합니다: 발신자가 다양한 사용 사례에서 후크를 유연하게 만들 수있는 옵션 또는 구성을 전달할 수 있도록합니다.
- 하드 코딩 로직을 피하십시오: 하드 코드 값이나 사용 방법에 대한 가정을 피함으로써 후크를 일반적인 상태로 유지하십시오.
- 후크의 사용법을 문서화하십시오: 명확한 문서는 다른 프로젝트 나 다른 개발자에 의해 고리를 재사용 할 수 있도록하는 데 중요합니다.
사용자 정의 후크로 TypeScript를 활용합니다
TypeScript는 유형 안전 및 자동 완성을 추가하여 사용자 정의 후크의 재사용 성과 유지 가능성을 크게 향상시킬 수 있습니다. TypeScript로 사용자 정의 후크를 구축 할 때는 후크 매개 변수 및 반환 유형의 인터페이스를 정의 할 수 있습니다.
import { useState, useEffect } from 'react';
interface FetchResult {
data: T | null;
loading: boolean;
error: Error | null;
}
function useTypedFetch(url: string): FetchResult {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchData() {
try {
const response = await fetch(url);
const result: T = await response.json();
setData(result);
setLoading(false);
} catch (err) {
setError(err);
setLoading(false);
}
}
fetchData();
}, [url]);
return { data, loading, error };
}
이 예에서 useTypedFetch
후크는 일반적으로 유형 인수로 전달 된 데이터 유형으로 작동 할 수 있습니다.
결론
복잡한 시나리오를위한 맞춤형 반응 후크 구축은 코드베이스를 단순화하고 재사용 가능한 논리를 만드는 강력한 방법입니다. Debouncing을 처리하거나 글로벌 상태를 관리하거나 성능을 최적화하든 사용자 정의 후크를 사용하면 논리를 추상화하고 캡슐화 할 수 있으므로 React 구성 요소를 더 깨끗하고 유지 관리 할 수 있습니다.
커스텀 후크를 계속 구축하면 재사용 성, 확장 성 및 성능에 중점을 둡니다. 모범 사례를 따르고 고급 패턴을 활용하는 경우 특정 문제를 해결할뿐만 아니라 프로젝트에서 재사용 할 수있을 정도로 유연한 후크를 만들 수 있습니다.
Post Comment