반응 중인 후크로 API 호출 🧑🏽💻
물론 묘책은 없으며 작업 중인 프로젝트에 따라 다릅니다. 오늘 저는 통화에서 수행할 수 있고 새로운 아이디어를 위한 트리거가 될 수 있는 몇 가지 최적화를 공유할 것입니다.
문제
경력을 쌓는 동안 다양한 프로젝트에 참여했으며 다음과 같은 것을 발견했습니다.
예 1
export const MyComponent: React.FC = () => {
const [dogs, setDogs] = useState();
useEffect(() => {
fetch('/api/v1/dogs')
.then(r => r.json())
.then(json => setDogs(json));
});
return <DogsList dogs={dogs} />;
}
export const MyComponent2: React.FC = () => {
const [cats, setCats] = useState();
useEffect(() => {
fetch('/api/v1/cats')
.then(r => r.json())
.then(json => setData(json));
});
return <CatsList cats={cats} />;
}
아니면 이거:
예 2
const MyComponent: React.FC = () => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState();
const [dogs, setDogs] = useState();
useEffect(() => {
fetch('/api/v1/dogs')
.then(r => r.json())
.then(json => setDogs(json))
.catch(e => setError(e))
.finally(() => setLoading(false));
});
if (loading) {
return <div>Loading dogs</div>;
}
return <DogsList dogs={dogs} />;
}
보시다시피 코드가 복제되기 시작하고 컴포넌트 내부에 통신 로직을 배치하고 있습니다. 그리고 더 많은 로직을 추가하려는 경우, 즉 구성 요소가 마운트된 경우에만 상태를 설정하려는 경우에는 상황이 더욱 악화됩니다.
어떤 이유로 사람들은 때때로 우리가 이러한 모든 시나리오를 처리하고 코드를 더 깔끔하게 유지하기 위해 간단한 후크를 만들 수 있다는 것을 잊습니다.
Note: Of course, there are libraries to tackle this, but just for the purpose of this article I prefer we implement it by ourselves
1: 간단한 접근 방식
API에서 데이터를 검색하기 위한 새로운 후크의 작은 구현부터 시작하겠습니다. 우리는 여기서 이름을 지정하는 데 능숙하므로
useApi
라고 부르겠습니다.function useApi(url: string) {
const [data, setData] = useState();
useEffect(() => {
fetch(url)
.then(r => r.json())
.then(json => setData(json))
}, [url]) // Remember your dependencies
return data;
}
이 간단한 후크만 있으면 첫 번째 예를 다음과 같이 다시 작성할 수 있습니다.
export const MyComponent: React.FC = () => {
const dogs = useApi('/api/v1/dogs');
return <DogsList dogs={dogs} />;
}
export const MyComponent2: React.FC = () => {
const cats = useApi('/api/v1/cats');
return <CatsList cats={cats} />;
}
이것이 얼마나 깨끗한지 보십시오. 내 구성 요소는 이 API를 호출하는 방법에 대해 신경 쓰지 않습니다.
fetch
또는 axios
를 사용하는 경우 데이터가 거기에 있다는 것을 알 수 있습니다.개선을 위한 작은 발걸음
이것을 조금 더 반복해봅시다. 우리는 여기서 우리가 가진 어떤 힘을 잊어버렸습니다... 우리는 타이프스크립트를 가지고 있습니다! 그리고 우리에게 제공되는 가장 중요한 기능인 유형을 사용하지 않습니다.
function useApi<T>(url: string): T | undefined {
const [data, setData] = useState<T>();
useEffect(() => {
fetch(url)
.then(r => r.json())
.then(json => setData(json))
}, [url]) // Remember your dependencies
return data;
}
이제 구성 요소에서 적절한 유형으로 정적 유효성 검사를 할 것입니다.
export const MyComponent: React.FC = () => {
const dogs = useApi<Dog>('/api/v1/dogs');
return <DogsList dogs={dogs} />;
}
export const MyComponent2: React.FC = () => {
const cats = useApi<Cat>('/api/v1/cats');
return <CatsList cats={cats} />;
}
이 첫 번째 접근 방식은 다음과 같습니다.
2: 요청 상태 관리
이제
useApi
구현에 만족하므로 데이터를 기다리는 중이거나 리소스를 가져오는 중에 오류가 있는 경우 사용자에게 표시하려고 합니다.몇 가지 상태를 추가하고 튜플을 반환하면 다음을 달성할 수 있습니다.
function useApi<T>(url: string): [T | undefined, boolean, Error | undefined] {
const [data, setData] = useState<T>();
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error>();
useEffect(() => {
setLoading(true);
fetch(url)
.then(r => r.json())
.then(json => setData(json))
.catch(e => setError(e))
.finally(() => setLoading(false));
}, [url]) // Remember your dependencies
return [data, loading, error];
}
그런 다음 구성 요소에서:
const MyComponent: React.FC = () => {
const [dogs, loading, error] = useApi('/api/v1/dogs');
if (loading) {
return <div>Loading dogs</div>;
}
if (error) {
return <div>Oops!</div>;
}
return <DogsList dogs={dogs} />;
}
3(업데이트): 커뮤니케이션 개선
이제 추상화 계층을 마쳤으므로 또 다른 문제가 있습니다.
useEffect
만 사용하여 API를 호출하면 호출이 중복되거나(의견 감사합니다 😃) 캐시 또는 자동 새로 고침을 추가하려는 경우 위 디자인에 통합하기 어려울 수 있습니다.자체 후크가 있는 자체 레이어가 있으므로 원하는 라이브러리를 사용하여 변경할 수 있는 유연성이 있으며 변경하기 위해 전체 코드베이스를 리팩터링할 필요가 없습니다.
예를 들어
react-query
을 사용하려는 경우:import { useQuery } from 'react-query'
const fetcher = (url) => () => fetch(url).then(r => r.json());
function useApi<T>(url: string): [T | undefined, boolean, Error | undefined] {
const { data, isLoading, isError } = useQuery(url, fetcher(url));
return [data, isLoading, error];
}
그리고 구성 요소를 만질 필요가 없습니다.
Remember: This is for example purposes only, if you want to use react-query or another library read the documentation of the proper usage.
결론
이 접근 방식을 통해 모든 코드를 리팩토링할 필요 없이 결국 원하는 수정을 수행할 수 있는 사용자 지정 후크를 만들 수 있었습니다. 구성 요소 전체에서 반복되는 코드가 없으며 요청의 다양한 상태를 적절하게 처리하고 있습니다.
요청을 하기 위해 다른 라이브러리를 추가하는 것은 간단할 것이며 사용자가 사용할 라이브러리를 결정할 수 있도록
fetcher: (url: string) => Promise<T>
를 추출할 수도 있습니다.끝까지 읽어 주셔서 대단히 감사합니다. 조금이나마 도움이 되었기를 바랍니다 😃. 피드백은 항상 감사합니다.
Reference
이 문제에 관하여(반응 중인 후크로 API 호출 🧑🏽💻), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jor_exe/calling-your-apis-with-hooks-in-react-c30텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)